home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Utilities / MView / dlgproc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-30  |  20.8 KB  |  772 lines

  1. /*//////////////////////////////////////////////////////////////////////////////
  2. //
  3. // File: dlgproc.cpp
  4. //
  5. // Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  6. //
  7. //
  8. //////////////////////////////////////////////////////////////////////////////*/
  9.  
  10. #include "mviewpch.h"
  11.  
  12. // Mesage handler for about box.
  13. LRESULT CALLBACK 
  14. DlgProcSimplify(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  15. {
  16.     WORD nId = 0, nNotifyCode = 0;
  17.     char szBuf[256];
  18.     char *pTmp;
  19.     DWORD cVertices;
  20.  
  21.     switch (message)
  22.     {
  23.     case WM_INITDIALOG:
  24.         GXASSERT(g_pData->m_pmcSelectedMesh->bSimplifyMode 
  25.             || g_pData->m_pmcSelectedMesh->bPMMeshMode);
  26.  
  27.         if (g_pData->m_pmcSelectedMesh->bPMMeshMode)
  28.             cVertices = g_pData->m_pmcSelectedMesh->pPMMesh->GetNumVertices();                   
  29.         else
  30.             cVertices = g_pData->m_pmcSelectedMesh->pSimpMesh->GetNumVertices();                   
  31.  
  32.         sprintf(szBuf, "%d", cVertices);
  33.  
  34.         SetDlgItemText(hDlg, IDC_VERTEXCOUNT, szBuf);
  35.  
  36.         return TRUE;
  37.         
  38.     case WM_COMMAND:
  39.         nId = LOWORD(wParam);
  40.         nNotifyCode = HIWORD(wParam);
  41.         switch (nId)
  42.         {
  43.         case IDOK:
  44.             GetDlgItemText(hDlg, IDC_VERTEXCOUNT, szBuf, 255);
  45.             cVertices = (long) strtoul(szBuf, &pTmp, 10);
  46.             if (pTmp && (*pTmp != '\0'))
  47.                 goto e_Exit;
  48.  
  49.             g_pData->SetNumVertices(cVertices, true /*absolute*/);                   
  50.  
  51.             EndDialog(hDlg, 0);
  52.             return TRUE;
  53.         case IDCANCEL:
  54.             EndDialog(hDlg, 1);
  55.             return TRUE;
  56.         }
  57.         break;
  58.     }
  59.     return FALSE;
  60.  
  61. e_Exit:
  62.     MessageBox(NULL, "Please enter a valid number", "Simplify", MB_SYSTEMMODAL | MB_OK );
  63.     return TRUE;
  64. }
  65.  
  66. // Mesage handler for about box.
  67. LRESULT CALLBACK 
  68. DlgProcSimplifyFaces(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  69. {
  70.     WORD nId = 0, nNotifyCode = 0;
  71.     char szBuf[256];
  72.     char *pTmp;
  73.     DWORD cFaces;
  74.  
  75.     switch (message)
  76.     {
  77.     case WM_INITDIALOG:
  78.         GXASSERT(g_pData->m_pmcSelectedMesh->bSimplifyMode 
  79.             || g_pData->m_pmcSelectedMesh->bPMMeshMode);
  80.  
  81.         if (g_pData->m_pmcSelectedMesh->bPMMeshMode)
  82.             cFaces = g_pData->m_pmcSelectedMesh->pPMMesh->GetNumFaces();                   
  83.         else
  84.             cFaces = g_pData->m_pmcSelectedMesh->pSimpMesh->GetNumFaces();                   
  85.  
  86.         sprintf(szBuf, "%d", cFaces);
  87.  
  88.         SetDlgItemText(hDlg, IDC_VERTEXCOUNT, szBuf);
  89.  
  90.         return TRUE;
  91.         
  92.     case WM_COMMAND:
  93.         nId = LOWORD(wParam);
  94.         nNotifyCode = HIWORD(wParam);
  95.         switch (nId)
  96.         {
  97.         case IDOK:
  98.             GetDlgItemText(hDlg, IDC_VERTEXCOUNT, szBuf, 255);
  99.             cFaces = (long) strtoul(szBuf, &pTmp, 10);
  100.             if (pTmp && (*pTmp != '\0'))
  101.                 goto e_Exit;
  102.  
  103.             g_pData->SetNumFaces(cFaces, true /*absolute*/);                   
  104.  
  105.             EndDialog(hDlg, 0);
  106.             return TRUE;
  107.         case IDCANCEL:
  108.             EndDialog(hDlg, 1);
  109.             return TRUE;
  110.         }
  111.         break;
  112.     }
  113.     return FALSE;
  114.  
  115. e_Exit:
  116.     MessageBox(NULL, "Please enter a valid number", "Simplify", MB_SYSTEMMODAL | MB_OK );
  117.     return TRUE;
  118. }
  119.  
  120. void
  121. SetCheck(HWND hDlg, UINT id, BOOL bChecked)
  122. {
  123.     HWND hwndTemp;
  124.     int nCheck = bChecked ? BST_CHECKED : BST_UNCHECKED; 
  125.  
  126.     hwndTemp = GetDlgItem(hDlg, id);
  127.     SendMessage(hwndTemp, BM_SETCHECK, nCheck, 0);
  128. }
  129.  
  130. bool
  131. GetCheck(HWND hDlg, UINT id)
  132. {
  133.     HWND hwndTemp;
  134.  
  135.     hwndTemp = GetDlgItem(hDlg, id);
  136.     return BST_CHECKED == SendMessage(hwndTemp, BM_GETCHECK, 0, 0);
  137. }
  138.  
  139. LRESULT CALLBACK 
  140. DlgProcProperties(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  141. {
  142.     WORD nId = 0, nNotifyCode = 0;
  143.     DWORD dwFVF;
  144.     DWORD dwOptions;
  145.     D3DVERTEXELEMENT9 pDecl[MAX_FVF_DECL_SIZE];
  146.  
  147.     switch (message)
  148.     {
  149.     case WM_INITDIALOG:
  150.  
  151.         dwFVF = g_pData->m_pmcSelectedMesh->ptmDrawMesh->GetFVF();
  152.         dwOptions = g_pData->m_pmcSelectedMesh->ptmDrawMesh->GetOptions();
  153.  
  154.         SetCheck(hDlg, IDC_XYZ, true);
  155.         SetCheck(hDlg, IDC_NORMAL, dwFVF & D3DFVF_NORMAL);
  156.         SetCheck(hDlg, IDC_DIFFUSE, dwFVF & D3DFVF_DIFFUSE);
  157.         SetCheck(hDlg, IDC_SPECULAR, dwFVF & D3DFVF_SPECULAR);
  158.         SetCheck(hDlg, IDC_TEX1, dwFVF & D3DFVF_TEX1);
  159.  
  160.         SetCheck(hDlg, IDC_32BITINDEX, dwOptions & D3DXMESH_32BIT);
  161.  
  162.         return TRUE;
  163.         
  164.     case WM_COMMAND:
  165.         nId = LOWORD(wParam);
  166.         nNotifyCode = HIWORD(wParam);
  167.         switch (nId)
  168.         {
  169.         case IDOK:
  170.             dwFVF = g_pData->m_pmcSelectedMesh->ptmDrawMesh->GetFVF() | D3DFVF_XYZ;
  171.             dwOptions = g_pData->m_pmcSelectedMesh->ptmDrawMesh->GetOptions();
  172.  
  173.             if (GetCheck(hDlg, IDC_NORMAL))
  174.                 dwFVF |= D3DFVF_NORMAL;
  175.             else
  176.                 dwFVF &= ~D3DFVF_NORMAL;
  177.  
  178.             if (GetCheck(hDlg, IDC_DIFFUSE))
  179.                 dwFVF |= D3DFVF_DIFFUSE;
  180.             else
  181.                 dwFVF &= ~D3DFVF_DIFFUSE;
  182.  
  183.             if (GetCheck(hDlg, IDC_SPECULAR))
  184.                 dwFVF |= D3DFVF_SPECULAR;
  185.             else
  186.                 dwFVF &= ~D3DFVF_SPECULAR;
  187.  
  188.             if (GetCheck(hDlg, IDC_TEX1))
  189.                 dwFVF |= D3DFVF_TEX1;
  190.             else
  191.                 dwFVF &= ~D3DFVF_TEX1;
  192.  
  193.             if (GetCheck(hDlg, IDC_32BITINDEX))
  194.                 dwOptions |= D3DXMESH_32BIT;
  195.             else
  196.                 dwOptions &= ~D3DXMESH_32BIT;
  197.  
  198.             D3DXDeclaratorFromFVF(dwFVF, pDecl);
  199.             g_pData->ConvertSelectedMesh(dwOptions, pDecl);
  200.  
  201.             EndDialog(hDlg, 0);
  202.             return TRUE;
  203.         case IDCANCEL:
  204.             EndDialog(hDlg, 1);
  205.             return TRUE;
  206.         }
  207.         break;
  208.     }
  209.     return FALSE;
  210.  
  211. //e_Exit:
  212.     MessageBox(NULL, "Please enter a valid number", "Simplify", MB_SYSTEMMODAL | MB_OK );
  213.     return TRUE;
  214. }
  215.  
  216.  
  217. // Mesage handler for about box.
  218. LRESULT CALLBACK DlgProcAbout(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  219. {
  220.     switch (message)
  221.     {
  222.         case WM_INITDIALOG:
  223.         {
  224.             DWORD dwVersionMS = 0;
  225.             DWORD dwVersionLS = 0;
  226.  
  227.             TCHAR tsz[256];
  228.             TCHAR tszVersion[256];
  229.             ::GetDlgItemText( hDlg, IDC_VERSION, tsz, 256 );
  230.             // Retrieve the version number
  231.             TCHAR tszFileName[MAX_PATH];
  232.             ::GetModuleFileName( NULL, tszFileName, MAX_PATH );
  233.             DWORD dwVerSize, dwHandle;
  234.             dwVerSize = ::GetFileVersionInfoSize( tszFileName, &dwHandle );
  235.             if( dwVerSize )
  236.             {
  237.                 LPVOID pData = malloc( dwVerSize );
  238.                 if( pData )
  239.                 {
  240.                     ::GetFileVersionInfo( tszFileName, 0, dwVerSize, pData );
  241.                     VS_FIXEDFILEINFO *pffi;
  242.                     UINT uLen;
  243.                     ::VerQueryValue( pData, _T("\\"), (LPVOID*)&pffi, &uLen );
  244.                     dwVersionMS = pffi->dwFileVersionMS;
  245.                     dwVersionLS = pffi->dwFileVersionLS;
  246.                     free( pData );
  247.                 }
  248.             }
  249.             _sntprintf( tszVersion, 256, tsz, HIWORD( dwVersionMS ), LOWORD( dwVersionMS ),
  250.                                               HIWORD( dwVersionLS ), LOWORD( dwVersionLS ) );
  251.             tszVersion[255] = _T('\0');
  252.             ::SetDlgItemText( hDlg, IDC_VERSION, tszVersion );
  253.             return TRUE;
  254.         }
  255.  
  256.         case WM_COMMAND:
  257.             if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
  258.             {
  259.                 EndDialog(hDlg, LOWORD(wParam));
  260.                 return TRUE;
  261.             }
  262.             break;
  263.     }
  264.     return FALSE;
  265. }
  266.  
  267. // Mesage handler for about box.
  268. LRESULT CALLBACK 
  269. DlgProcOutput(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  270. {
  271.     WORD nId = 0;
  272.  
  273.     switch (message)
  274.     {
  275.     case WM_INITDIALOG:
  276.         GXASSERT(g_pData->pvDialogData != NULL);
  277.  
  278.         SetDlgItemText(hDlg, IDC_CONSOLE, (char*)g_pData->pvDialogData);
  279.  
  280.         return TRUE;
  281.         
  282.     case WM_COMMAND:
  283.         nId = LOWORD(wParam);
  284.         switch (nId)
  285.         {
  286.         case IDOK:
  287.             EndDialog(hDlg, 0);
  288.             return TRUE;
  289.         case IDCANCEL:
  290.             EndDialog(hDlg, 1);
  291.             return TRUE;
  292.         }
  293.         break;
  294.     }
  295.     return FALSE;
  296. }
  297.  
  298. const char *x_rgszUsageStrings[] = 
  299. {  
  300.     "Position",    // D3DDECLUSAGE_POSITION = 0,
  301.     "BlendWeight", // D3DDECLUSAGE_BLENDWEIGHT,   // 1
  302.     "BlendIndices",// D3DDECLUSAGE_BLENDINDICES,  // 2
  303.     "Normal",      // D3DDECLUSAGE_NORMAL,        // 3
  304.     "PSize",       // D3DDECLUSAGE_PSIZE,         // 4
  305.     "Texcoord",    // D3DDECLUSAGE_TEXCOORD,      // 5
  306.     "Tangent",     // D3DDECLUSAGE_TANGENT,       // 6
  307.     "Binormal",    // D3DDECLUSAGE_BINORMAL,      // 7
  308.     "TessFactor",  // D3DDECLUSAGE_TESSFACTOR,    // 8
  309.     "PositionT",   // D3DDECLUSAGE_POSITIONT,     // 9
  310.     "Color",       // D3DDECLUSAGE_COLOR,         // 10
  311.     "Fog",         // D3DDECLUSAGE_FOG,           // 11
  312.     "Depth",       // D3DDECLUSAGE_DEPTH,         // 12
  313.     "Sample"       // D3DDECLUSAGE_SAMPLE,        // 13
  314. };
  315.  
  316.  
  317. GatherVertexInfo(
  318.     DWORD dwVertex, 
  319.     PBYTE pbPoints, 
  320.     LPD3DVERTEXELEMENT9 pDecl,
  321.     char **pszOutput)
  322. {
  323.     char szBuf[120];
  324.     char * szOutput = NULL;
  325.     HRESULT hr = S_OK;
  326.     CD3DXCrackDecl1 cd(pDecl);
  327.     PBYTE pbPoint;
  328.     D3DXVECTOR3 *pvTemp;
  329.     DWORD iWeight;
  330.     DWORD cWeights;
  331.     float *pfWeights;
  332.     D3DXCOLOR colorTemp;
  333.     float *pfTexCoords;
  334.     DWORD iTexCoord;
  335.     DWORD cComponents;
  336.     DWORD iComponent;
  337.     FLOAT rgfValues[4];
  338.     const char *szUsage;
  339.     LPD3DVERTEXELEMENT9 pDeclCur;
  340.     DWORD iValue;
  341.     DWORD cValues;
  342.  
  343.     cd.SetStreamSource(0, pbPoints, cd.m_cBytesPerVertex);
  344.  
  345.     szOutput = new char[120 * 30/*vertex info*/];
  346.     if (szOutput == NULL)
  347.     {
  348.         hr = E_OUTOFMEMORY;
  349.         goto e_Exit;
  350.     }
  351.  
  352.     sprintf(szOutput, "Information for Vertex %d:\r\n", dwVertex);
  353.  
  354.     pDeclCur = pDecl;
  355.     while (pDeclCur->Stream != 0xff)
  356.     {
  357.  
  358.         szUsage = x_rgszUsageStrings[pDeclCur->Usage];
  359.  
  360.         sprintf(szBuf, "\t%s%d (", szUsage, pDeclCur->UsageIndex);
  361.         strcat(szOutput, szBuf);
  362.  
  363.         cd.Decode(pDeclCur, dwVertex, rgfValues, 4);
  364.  
  365.         cValues = x_rgcbFields[pDeclCur->Type];
  366.         for (iValue = 0; iValue < cValues; iValue++)
  367.         {
  368.             if (iValue == (cValues-1))
  369.                 sprintf(szBuf, "%f", rgfValues[iValue]);
  370.             else
  371.                 sprintf(szBuf, "%f,", rgfValues[iValue]);
  372.  
  373.             strcat(szOutput, szBuf);
  374.         }
  375.  
  376.         strcat(szOutput, ")\r\n");
  377.  
  378.         pDeclCur++;
  379.     }
  380.  
  381.     *pszOutput = szOutput;
  382.     szOutput = NULL;
  383.  
  384. e_Exit:
  385.     delete []szOutput;
  386.     return hr;
  387. }
  388.  
  389. HRESULT 
  390. GatherVertexInfoHelper(LPD3DXBASEMESH pMesh, DWORD dwVertex, char **pszOutput)
  391. {
  392.     HRESULT hr = S_OK;
  393.     char *szOutput = NULL;
  394.     PBYTE pbPoints;
  395.     PBYTE pIndices;
  396.     DWORD dwFVF;
  397.     BOOL b16BitMesh;
  398.     D3DVERTEXELEMENT9 pDecl[MAX_FVF_DECL_SIZE];
  399.  
  400.     pMesh->LockVertexBuffer(D3DLOCK_READONLY, (PVOID*)&pbPoints);
  401.  
  402.     pMesh->GetDeclaration(pDecl);
  403.     hr = GatherVertexInfo(dwVertex, pbPoints, pDecl, &szOutput);
  404.     if (FAILED(hr))
  405.         goto e_Exit;
  406.  
  407.     *pszOutput = szOutput;
  408.     szOutput = NULL;
  409.  
  410. e_Exit:
  411.     if (pbPoints != NULL)
  412.     {
  413.         pMesh->UnlockVertexBuffer();
  414.     }
  415.  
  416.     delete []szOutput;
  417.     return hr;
  418. }
  419.  
  420. // Mesage handler for about box.
  421. LRESULT CALLBACK 
  422. DlgProcVertexInfo(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  423. {
  424.     WORD nId = 0;
  425.     char szBuf[120];
  426.     char *pTmp;
  427.     char *szOutput = NULL;
  428.     DWORD dwVertex;
  429.  
  430.     switch (message)
  431.     {
  432.     case WM_INITDIALOG:
  433.         sprintf(szBuf, "%d", g_pData->m_dwVertexSelected);
  434.         SetDlgItemText(hDlg, IDC_SELECTEDVERTEX, szBuf);
  435.  
  436.         GatherVertexInfoHelper(g_pData->m_pmcSelectedMesh->ptmDrawMesh, g_pData->m_dwVertexSelected, &szOutput);
  437.         SetDlgItemText(hDlg, IDC_CONSOLE, szOutput);
  438.  
  439.         delete []szOutput;
  440.  
  441.         return TRUE;
  442.         
  443.     case WM_COMMAND:
  444.         nId = LOWORD(wParam);
  445.         switch (nId)
  446.         {
  447.         case IDOK:
  448.             EndDialog(hDlg, 0);
  449.             return TRUE;
  450.         case IDCANCEL:
  451.             EndDialog(hDlg, 1);
  452.             return TRUE;
  453.         case IDC_GETVERTEXINFO:
  454.  
  455.             GetDlgItemText(hDlg, IDC_SELECTEDVERTEX, szBuf, 120);
  456.             dwVertex = (long) strtoul(szBuf, &pTmp, 10);
  457.             if (pTmp && (*pTmp != '\0'))
  458.                 return TRUE;
  459.  
  460.             if (dwVertex < g_pData->m_pmcSelectedMesh->ptmDrawMesh->GetNumVertices())
  461.             {
  462.                 GatherVertexInfoHelper(g_pData->m_pmcSelectedMesh->ptmDrawMesh, dwVertex, &szOutput);
  463.                 g_pData->m_dwVertexSelected = dwVertex;
  464.             }
  465.             else
  466.             {
  467.                 szOutput = new char[120];
  468.                 if (szOutput == NULL)
  469.                     return FALSE;
  470.  
  471.                 sprintf(szOutput, "Index %d is not a valid index.  There are %d vertices in the selected mesh", dwVertex, g_pData->m_pmcSelectedMesh->ptmDrawMesh->GetNumVertices());
  472.             }
  473.  
  474.             SetDlgItemText(hDlg, IDC_CONSOLE, szOutput);
  475.  
  476.             delete []szOutput;
  477.  
  478.             return TRUE;
  479.         }
  480.         break;
  481.     }
  482.     return FALSE;
  483. }
  484.  
  485.  
  486.  
  487. template<class UINT_IDX, unsigned int UNUSED>
  488. HRESULT
  489. GatherFaceInfo(
  490.     LPD3DXBASEMESH pMesh, 
  491.     DWORD dwFace, 
  492.     UINT_IDX *pwFaces, 
  493.     DWORD *rgdwAdjacency,
  494.     PBYTE pbPoints, 
  495.     LPD3DVERTEXELEMENT9 pDecl, 
  496.     char **pszOutput, 
  497.     UINT_IDX Dummy)
  498. {
  499.     char szBuf[120];
  500.     char * szOutput = NULL;
  501.     HRESULT hr = S_OK;
  502.     DWORD iIndex;
  503.     char *szVertexInfo;
  504.  
  505.     szOutput = new char[120 * (10 /*face info*/+ 60/*vertex info*/)];
  506.     if (szOutput == NULL)
  507.     {
  508.         hr = E_OUTOFMEMORY;
  509.         goto e_Exit;
  510.     }
  511.  
  512.     sprintf(szOutput, "Information for Face %d:\r\n\r\n", dwFace);
  513.  
  514.     sprintf(szBuf, "Vertex Indices:\r\n");
  515.     strcat(szOutput, szBuf);
  516.     for (iIndex = 0; iIndex < 3; iIndex++)
  517.     {
  518.         sprintf(szBuf, "Index %d: %d\r\n", iIndex, pwFaces[dwFace*3 + iIndex]);
  519.         strcat(szOutput, szBuf);
  520.     }
  521.  
  522.     sprintf(szBuf, "\r\nAdjacent Face Indices:\r\n");
  523.     strcat(szOutput, szBuf);
  524.     for (iIndex = 0; iIndex < 3; iIndex++)
  525.     {
  526.         if (rgdwAdjacency[dwFace*3 + iIndex] != UNUSED32)
  527.             sprintf(szBuf, "AdjIndex %d: %d\r\n", iIndex, rgdwAdjacency[dwFace*3 + iIndex]);
  528.         else
  529.             sprintf(szBuf, "AdjIndex %d: UNUSED\r\n", iIndex);
  530.  
  531.         strcat(szOutput, szBuf);
  532.     }
  533.  
  534.     strcat(szOutput, "\r\n");
  535.     for (iIndex = 0; iIndex < 3; iIndex++)
  536.     {
  537.         // gather the vertex info to include with the face info
  538.         hr = GatherVertexInfo(pwFaces[dwFace*3 + iIndex], pbPoints, pDecl, &szVertexInfo);
  539.         if (FAILED(hr))
  540.             goto e_Exit;
  541.  
  542.         strcat(szOutput, szVertexInfo);
  543.         strcat(szOutput, "\r\n");
  544.         delete []szVertexInfo;
  545.     }
  546.  
  547.  
  548.     *pszOutput = szOutput;
  549.     szOutput = NULL;
  550.  
  551. e_Exit:
  552.     delete []szOutput;
  553.     return hr;
  554. }
  555.  
  556. HRESULT
  557. GatherFaceInfoHelper(
  558.     LPD3DXBASEMESH pMesh, 
  559.     DWORD dwFace, 
  560.     DWORD *rgdwAdjacency,
  561.     char **pszOutput)
  562. {
  563.     HRESULT hr = S_OK;
  564.     char *szOutput = NULL;
  565.     PBYTE pbPoints;
  566.     PBYTE pIndices;
  567.     UINT16 Dummy16 = 0;
  568.     UINT32 Dummy32 = 0;
  569.     DWORD dwFVF;
  570.     BOOL b16BitMesh;
  571.     D3DVERTEXELEMENT9 pDecl[MAX_FVF_DECL_SIZE];
  572.  
  573.     pMesh->LockIndexBuffer(D3DLOCK_READONLY, (PVOID*)&pIndices);
  574.     pMesh->LockVertexBuffer(D3DLOCK_READONLY, (PVOID*)&pbPoints);
  575.  
  576.     pMesh->GetDeclaration(pDecl);
  577.     b16BitMesh = !(pMesh->GetOptions() & D3DXMESH_32BIT);
  578.  
  579.     // first gather the face info
  580.     if (b16BitMesh)
  581.         hr = GatherFaceInfo<UINT16,UNUSED16>(pMesh, dwFace, (UINT16*)pIndices, rgdwAdjacency, pbPoints, pDecl, &szOutput, Dummy16);
  582.     else
  583.         hr = GatherFaceInfo<UINT32,UNUSED32>(pMesh, dwFace, (UINT32*)pIndices, rgdwAdjacency, pbPoints, pDecl, &szOutput, Dummy32);
  584.  
  585.     if (FAILED(hr))
  586.         goto e_Exit;
  587.  
  588.     *pszOutput = szOutput;
  589.     szOutput = NULL;
  590.  
  591. e_Exit:
  592.     if (pIndices != NULL)
  593.     {
  594.         pMesh->UnlockIndexBuffer();
  595.     }
  596.  
  597.     if (pbPoints != NULL)
  598.     {
  599.         pMesh->UnlockVertexBuffer();
  600.     }
  601.  
  602.     delete []szOutput;
  603.     return hr;
  604. }
  605.  
  606. // Mesage handler for about box.
  607. LRESULT CALLBACK 
  608. DlgProcFaceInfo(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  609. {
  610.     WORD nId = 0;
  611.     char szBuf[120];
  612.     char *pTmp;
  613.     char *szOutput = NULL;
  614.     DWORD dwFace;
  615.  
  616.     switch (message)
  617.     {
  618.     case WM_INITDIALOG:
  619.         sprintf(szBuf, "%d", g_pData->m_dwFaceSelected);
  620.         SetDlgItemText(hDlg, IDC_SELECTEDFACE, szBuf);
  621.  
  622.         GatherFaceInfoHelper(g_pData->m_pmcSelectedMesh->ptmDrawMesh, g_pData->m_dwFaceSelected, 
  623.                                 g_pData->m_pmcSelectedMesh->rgdwAdjacency, &szOutput);
  624.         SetDlgItemText(hDlg, IDC_CONSOLE, szOutput);
  625.         
  626.         delete []szOutput;
  627.  
  628.         return TRUE;
  629.         
  630.     case WM_COMMAND:
  631.         nId = LOWORD(wParam);
  632.         switch (nId)
  633.         {
  634.         case IDOK:
  635.             EndDialog(hDlg, 0);
  636.             return TRUE;
  637.         case IDCANCEL:
  638.             EndDialog(hDlg, 1);
  639.             return TRUE;
  640.         case IDC_GETFACEINFO:
  641.  
  642.             {
  643.  
  644.             GetDlgItemText(hDlg, IDC_SELECTEDFACE, szBuf, 120);
  645.             dwFace = (long) strtoul(szBuf, &pTmp, 10);
  646.             if (pTmp && (*pTmp != '\0'))
  647.                 return TRUE;
  648.  
  649.             if (dwFace < g_pData->m_pmcSelectedMesh->ptmDrawMesh->GetNumFaces())
  650.             {
  651.                 GatherFaceInfoHelper(g_pData->m_pmcSelectedMesh->ptmDrawMesh, dwFace, 
  652.                                         g_pData->m_pmcSelectedMesh->rgdwAdjacency, &szOutput);
  653.  
  654.                 g_pData->m_dwFaceSelected = dwFace;
  655.             }
  656.             else
  657.             {
  658.                 szOutput = new char[120];
  659.                 if (szOutput == NULL)
  660.                     return FALSE;
  661.  
  662.                 sprintf(szOutput, "Index %d is not a valid index.  There are %d faces in the selected mesh", dwFace, g_pData->m_pmcSelectedMesh->ptmDrawMesh->GetNumFaces());
  663.             }
  664.  
  665.             // now display it
  666.             SetDlgItemText(hDlg, IDC_CONSOLE, szOutput);
  667.  
  668.             delete []szOutput;
  669.             }
  670.  
  671.             return TRUE;
  672.         }
  673.         break;
  674.     }
  675.     return FALSE;
  676. }
  677.  
  678.  
  679. HRESULT
  680. GatherMeshInfo
  681.     (
  682.     SMeshContainer *pmc, 
  683.     char **pszOutput
  684.     )
  685. {
  686.     HRESULT hr = S_OK;
  687.     char *szOutput = NULL;
  688.     char szBuf[120];
  689.     DWORD cVertices;
  690.     DWORD cFaces;
  691.  
  692.     szOutput = new char[120 * 20];
  693.     if (szOutput == NULL)
  694.     {
  695.         hr = E_OUTOFMEMORY;
  696.         goto e_Exit;
  697.     }
  698.  
  699.     cVertices = pmc->ptmDrawMesh->GetNumVertices();
  700.     cFaces = pmc->ptmDrawMesh->GetNumFaces();
  701.  
  702.     if (pmc->pPMMesh != NULL)
  703.     {
  704.         sprintf(szOutput, "Information about selected progressive mesh:\r\n");
  705.  
  706.         sprintf(szBuf, "\tMin number of faces   : %d\r\n", pmc->pPMMesh->GetMinFaces());
  707.         strcat(szOutput, szBuf);
  708.         sprintf(szBuf, "\tCur number of faces   : %d\r\n", cFaces);
  709.         strcat(szOutput, szBuf);
  710.         sprintf(szBuf, "\tMax number of faces   : %d\r\n\r\n", pmc->pPMMesh->GetMaxFaces());
  711.         strcat(szOutput, szBuf);
  712.  
  713.         sprintf(szBuf, "\tMin number of vertices: %d\r\n", pmc->pPMMesh->GetMinVertices());
  714.         strcat(szOutput, szBuf);
  715.         sprintf(szBuf, "\tCur number of vertices: %d\r\n", cVertices);
  716.         strcat(szOutput, szBuf);
  717.         sprintf(szBuf, "\tMax number of vertices: %d\r\n", pmc->pPMMesh->GetMaxVertices());
  718.         strcat(szOutput, szBuf);
  719.     }
  720.     else
  721.     {
  722.         sprintf(szOutput, "Information about selected mesh:\r\n");
  723.  
  724.         sprintf(szBuf, "\tNumber of faces   : %d\r\n", cFaces);
  725.         strcat(szOutput, szBuf);
  726.         sprintf(szBuf, "\tNumber of vertices: %d\r\n", cVertices);
  727.         strcat(szOutput, szBuf);
  728.     }
  729.  
  730.     *pszOutput = szOutput;
  731.     szOutput = NULL;
  732.  
  733. e_Exit:
  734.     delete []szOutput;
  735.     return hr;
  736. }
  737.  
  738. // Mesage handler for about box.
  739. LRESULT CALLBACK 
  740. DlgProcMeshInfo(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  741. {
  742.     WORD nId = 0;
  743.     char szBuf[120];
  744.     char *pTmp;
  745.     char *szOutput = NULL;
  746.     DWORD dwVertex;
  747.  
  748.     switch (message)
  749.     {
  750.     case WM_INITDIALOG:
  751.         GatherMeshInfo(g_pData->m_pmcSelectedMesh, &szOutput);
  752.         SetDlgItemText(hDlg, IDC_CONSOLE, szOutput);
  753.  
  754.         delete []szOutput;
  755.  
  756.         return TRUE;
  757.         
  758.     case WM_COMMAND:
  759.         nId = LOWORD(wParam);
  760.         switch (nId)
  761.         {
  762.         case IDOK:
  763.             EndDialog(hDlg, 0);
  764.             return TRUE;
  765.         case IDCANCEL:
  766.             EndDialog(hDlg, 1);
  767.             return TRUE;
  768.         }
  769.     }
  770.     return FALSE;
  771. }
  772.