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 / util.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-09-27  |  30.9 KB  |  941 lines

  1. #include "mviewpch.h"
  2.  
  3.  
  4.  
  5.  
  6. // find the first valid technique that also matches the desired skinning characteristics
  7. HRESULT
  8. D3DXCalcEffectSkinningSupport
  9.     (
  10.     LPD3DXEFFECT pEffect, 
  11.     DWORD *pSkinningTypesSupported
  12.     )
  13. {
  14.     HRESULT hr = S_OK;
  15.     D3DXEFFECT_DESC EffectDesc;
  16.     DWORD dwTechBlendPaletteSize;
  17.     DWORD cTechBlendWeights;
  18.     UINT iTech;
  19.     char szBuf[256];
  20.     D3DXTECHNIQUE_DESC TechDesc;
  21.     D3DXHANDLE hOrigTechnique, hTech;
  22.     DWORD dwOut;
  23.     INT iTemp;
  24.  
  25.     if ((pEffect == NULL) || (pSkinningTypesSupported == NULL))
  26.     {
  27. #ifdef DBG
  28.         if (pEffect == NULL)
  29.             DPF(0, "D3DXCalcEffectSkinningSupport: pEffect cannot be NULL");
  30.         else if (pSkinningTypesSupported == NULL)
  31.             DPF(0, "D3DXCalcEffectSkinningSupport: pSkinningTypesSupported cannot be NULL");
  32. #endif
  33.         hr = D3DERR_INVALIDCALL;
  34.         goto e_Exit;
  35.     }
  36.  
  37.     *pSkinningTypesSupported = 0;
  38.     dwOut = 0;
  39.  
  40.     pEffect->GetDesc(&EffectDesc);
  41.     if (NULL == (hOrigTechnique = pEffect->GetCurrentTechnique()))
  42.     {
  43.         DPF(0, "D3DXCalcEffectSkinningSupport: Could not get current technique");
  44.         hr = E_FAIL;
  45.         goto e_Exit;
  46.     }
  47.  
  48.     for (iTech = 0; iTech < EffectDesc.Techniques; iTech++)
  49.     {
  50.         hTech = pEffect->GetTechnique(iTech);
  51.  
  52.         hr = pEffect->SetTechnique(hTech);
  53.         if (FAILED(hr))
  54.             goto e_Exit;
  55.  
  56.         // Validate the effect, otherwise we will include info that will not be valid
  57.         hr = pEffect->ValidateTechnique(NULL);
  58.         if (FAILED(hr))
  59.         {
  60.             hr = S_OK;
  61.             continue;
  62.         }
  63.  
  64.         // set the technique as current to try and validate it
  65.         hr = pEffect->GetTechniqueDesc(hTech, &TechDesc);
  66.         if (FAILED(hr))
  67.             goto e_Exit;
  68.  
  69.         if (TechDesc.Name != NULL)
  70.         {
  71.             _snprintf(szBuf, 256, "%s_BlendWeights", TechDesc.Name);
  72.             hr = pEffect->GetInt(szBuf, &iTemp);
  73.             cTechBlendWeights = (DWORD)iTemp;
  74.             if (FAILED(hr))
  75.             {
  76.                 // set to all blend weights valid special value if not defined
  77.                 cTechBlendWeights = UNUSED32;
  78.             }
  79.             else if (cTechBlendWeights > 3)
  80.             {
  81.                 DPF(0, "D3DXCalcEffectSkinningSupport: More than 3 blend weights not supported. ignoring technique %s", TechDesc.Name);
  82.                 continue;
  83.             }
  84.  
  85.             _snprintf(szBuf, 256, "%s_BlendPaletteSize", TechDesc.Name);
  86.             hr = pEffect->GetInt(szBuf, &iTemp);
  87.             dwTechBlendPaletteSize = (DWORD)iTemp;
  88.             if (FAILED(hr))
  89.             {
  90.                 // set to no blend palette value if not defined
  91.                 dwTechBlendPaletteSize = 0;
  92.             }
  93.  
  94.             if (dwTechBlendPaletteSize == 0)
  95.             {
  96.                 // Non-Indexed blending technique with n weights
  97.                 dwOut |= 1 << (cTechBlendWeights + D3DXST_NONINDEXEDSHIFT);
  98.             }
  99.             else  // dwTechBlendPaletteSize > 0
  100.             {
  101.                 // Indexed blending technique with n weights
  102.                 dwOut |= 1 << (cTechBlendWeights + D3DXST_INDEXEDSHIFT);
  103.             }
  104.         }
  105.         else  // if the technique is not named... just asume that all non-indexed modes supported
  106.         {
  107.             dwOut |= D3DXST_NONINDEXEDMASK;
  108.         }
  109.     }
  110.  
  111.     pEffect->SetTechnique(hOrigTechnique);
  112.  
  113.     *pSkinningTypesSupported = dwOut;
  114.     
  115. e_Exit:
  116.     return hr;
  117. }
  118.  
  119. // find the first valid technique that also matches the desired skinning characteristics
  120. HRESULT
  121. SelectTechnique
  122.     (
  123.     LPD3DXEFFECT pEffect, 
  124.     DWORD dwSkinningMode
  125.     )
  126. {
  127.     HRESULT hr = S_OK;
  128.     D3DXEFFECT_DESC EffectDesc;
  129.     D3DXTECHNIQUE_DESC TechDesc;
  130.     DWORD dwTechBlendPaletteSize;
  131.     DWORD cTechBlendWeights;
  132.     UINT iTech;
  133.     char szBuf[256];
  134.     BOOL bFound = FALSE;
  135.     INT iTemp;
  136.     D3DXHANDLE hTech;
  137.  
  138.     pEffect->GetDesc(&EffectDesc);
  139.  
  140.     for (iTech = 0; iTech < EffectDesc.Techniques; iTech++)
  141.     {
  142.         hTech = pEffect->GetTechnique(iTech);
  143.  
  144.         // set the technique as current to try and validate it
  145.         hr = pEffect->SetTechnique(hTech);
  146.         if (FAILED(hr))
  147.             goto e_Exit;
  148.  
  149.         // get the name of the technique to check for validity for skinning
  150.         hr = pEffect->GetTechniqueDesc(NULL, &TechDesc);
  151.         if (FAILED(hr))
  152.             goto e_Exit;
  153.  
  154.         if (TechDesc.Name != NULL)
  155.         {
  156.             D3DXHANDLE Handle = pEffect->GetAnnotationByName(hTech, "BlendWeights");
  157.             if (Handle == NULL)
  158.             {
  159.                 // set to all blend weights valid special value if not defined
  160.                 cTechBlendWeights = UNUSED32;
  161.                 hr = S_OK;
  162.             }
  163.             else 
  164.             {
  165.                 hr = pEffect->GetInt(Handle, &iTemp);
  166.                 cTechBlendWeights = (DWORD)iTemp;
  167.  
  168.                 if (FAILED(hr))
  169.                 {
  170.                     // set to all blend weights valid special value if not defined
  171.                     cTechBlendWeights = UNUSED32;
  172.                     hr = S_OK;
  173.                 }
  174.                 else if (cTechBlendWeights > 3)
  175.                 {
  176.                     DPF(0, "MView: More than 3 blend weights not supported. ignoring technique %s", TechDesc.Name);
  177.                     continue;
  178.                 }
  179.             }
  180.  
  181.             Handle = pEffect->GetAnnotationByName(hTech, "BlendPaletteSize");
  182.             if (Handle == NULL)
  183.             {
  184.                 // set to all blend indices valid special value if not defined
  185.                 dwTechBlendPaletteSize = 0;
  186.             }
  187.             else
  188.             {
  189.                 hr = pEffect->GetInt(Handle, &iTemp);
  190.                 dwTechBlendPaletteSize = (DWORD)iTemp;
  191.                 if (FAILED(hr))
  192.                 {
  193.                     // set to all blend indices valid special value if not defined
  194.                     dwTechBlendPaletteSize = 0;
  195.                 }
  196.             }
  197.  
  198.             // if indexed skinning technique
  199.             if (dwTechBlendPaletteSize > 0)
  200.             {
  201.                 // check for the specific skinning weight mode
  202.                 if ( !(dwSkinningMode & (1 << (cTechBlendWeights + D3DXST_INDEXEDSHIFT)) ))
  203.                 {
  204.                     continue;
  205.                 }
  206.             }
  207.             // if non-indexed skinning technique
  208.             else
  209.             {
  210.                 // check for the specific skinning weight mode
  211.                 if ( (cTechBlendWeights != UNUSED32) && !(dwSkinningMode & (1 << (cTechBlendWeights + D3DXST_NONINDEXEDSHIFT)) ))
  212.                 {
  213.                     continue;
  214.                 }
  215.             }
  216.         }
  217.         else  // if the technique is not named... just assume that non-indexed skinning is supported
  218.         {
  219.             // check for non-indexed skinning and go on if not supported
  220.             if (!(dwSkinningMode & D3DXST_NONINDEXEDMASK))
  221.                 continue;
  222.         }
  223.  
  224.         // Validate the effect 
  225.         hr = pEffect->ValidateTechnique(NULL);
  226.         if (FAILED(hr))
  227.         {
  228.             hr = S_OK;
  229.             continue;
  230.         }
  231.  
  232.         // found one that works!
  233.         bFound = TRUE;
  234.         break;
  235.     }
  236.  
  237.     if (!bFound)
  238.     {
  239.         hr = E_FAIL;
  240.     }
  241.     
  242. e_Exit:
  243.     return hr;
  244. }
  245.  
  246. DWORD GetNumInfl
  247.     (
  248.     DWORD dwSkinningSupport
  249.     )
  250. {
  251.  
  252.     switch(dwSkinningSupport)
  253.     {
  254.  
  255.         case D3DXST_UNSKINNED:
  256.             return 1;
  257.         case D3DXST_1WEIGHT:        
  258.             return 2;
  259.         case D3DXST_2WEIGHT:
  260.             return 3;
  261.         case D3DXST_3WEIGHT:        
  262.             return 4;
  263.  
  264.         case D3DXST_0WEIGHTINDEXED: 
  265.             return 1;
  266.         case D3DXST_1WEIGHTINDEXED: 
  267.             return 2;
  268.         case D3DXST_2WEIGHTINDEXED: 
  269.             return 3;
  270.         case D3DXST_3WEIGHTINDEXED: 
  271.             return 4;
  272.  
  273.         default:
  274.         
  275.             // more than one bit is set, so fail
  276.             GXASSERT(0);
  277.             return 0;
  278.     }
  279. }
  280.  
  281. HRESULT
  282. SetEffectMeshInfo
  283.     (
  284.     LPD3DXEFFECT pEffect, 
  285.     LPD3DXVECTOR3 pCenter,
  286.     FLOAT fRadius
  287.     )
  288. {
  289.     UINT iParam;
  290.     D3DXHANDLE hParam;
  291.  
  292.     D3DXEFFECT_DESC EffectDesc;
  293.     D3DXPARAMETER_DESC ParamDesc;
  294.  
  295.     pEffect->GetDesc(&EffectDesc);
  296.  
  297.     // first find all matrix parameters that are present and used that we know about
  298.     for (iParam = 0; iParam < EffectDesc.Parameters; iParam++)
  299.     {
  300.         hParam = pEffect->GetParameter(NULL, iParam);
  301.  
  302.         pEffect->GetParameterDesc(hParam, &ParamDesc);
  303.  
  304.         if (ParamDesc.Semantic == NULL)
  305.             continue;
  306.  
  307.         if (ParamDesc.Class != D3DXPC_VECTOR)
  308.         {
  309.             if (lstrcmpi("meshcenter", ParamDesc.Semantic) == 0)
  310.             {
  311.                 D3DXVECTOR4 vCenter = *pCenter;
  312.                 pEffect->SetVector(hParam, &vCenter);
  313.             }
  314.         }
  315.         else if (ParamDesc.Class != D3DXPC_SCALAR)
  316.         {
  317.             if (lstrcmpi("meshradius", ParamDesc.Semantic) == 0)
  318.             {
  319.                 pEffect->SetFloat(hParam, fRadius);
  320.             }
  321.         }
  322.  
  323.     }
  324.  
  325.     return S_OK;
  326. }
  327.  
  328. const char *x_szWorld = "WORLD";
  329. const UINT x_cchWorld = 5;
  330. const char *x_szWorldInvTrans = "WorldInvTrans";
  331. const UINT x_cchWorldInvTrans = 14;
  332.  
  333. HRESULT GenerateEffectInfo
  334.     (
  335.     LPD3DXEFFECT pEffect, 
  336.     SEffectInfo *pEffectInfo
  337.     )
  338. {
  339.     HRESULT hr = S_OK;
  340.     UINT iParam;
  341.     char *szNumber;
  342.     char *szEnd;
  343.     char szBuf[80];
  344.     D3DXEFFECT_DESC EffectDesc;
  345.     D3DXPARAMETER_DESC ParamDesc;
  346.     BOOL bAParamNotFound;
  347.     D3DXHANDLE hParam;
  348.  
  349.     if ((pEffectInfo == NULL) || (pEffect == NULL))
  350.     {
  351. #ifdef DBG
  352.         if (pEffectInfo == NULL)
  353.             DPF(0, "D3DXGenerateEffectInfo: pEffectInfo cannot be NULL");
  354.         else if (pEffect == NULL)
  355.             DPF(0, "D3DXGenerateEffectInfo: pEffect cannot be NULL");
  356. #endif
  357.         hr = D3DERR_INVALIDCALL;
  358.         goto e_Exit;
  359.     }
  360.  
  361.     // intialize all indicess to be all 0xff (meaning not used)
  362.     memset(pEffectInfo, 0, sizeof(SEffectInfo));
  363.  
  364.     pEffectInfo->cWorlds = 0;
  365.     pEffectInfo->cWorldInvTrans = 0;
  366.  
  367.     pEffect->GetDesc(&EffectDesc);
  368.  
  369.     // first find all matrix parameters that are present and used that we know about
  370.     for (iParam = 0; iParam < EffectDesc.Parameters; iParam++)
  371.     {
  372.         hParam = pEffect->GetParameter(NULL, iParam);
  373.  
  374.         // only worry about a parameter if this technique uses it
  375.         if (!pEffect->IsParameterUsed(hParam, NULL))
  376.             continue;
  377.  
  378.         pEffect->GetParameterDesc(hParam, &ParamDesc);
  379.  
  380.         // only look at variables with semantics
  381.         if (ParamDesc.Semantic == NULL)
  382.             continue;
  383.  
  384.         if (ParamDesc.Class == D3DXPC_SCALAR)
  385.         {
  386.             if (lstrcmpi("time", ParamDesc.Semantic) == 0)
  387.             {
  388.                 pEffectInfo->hTime = hParam;
  389.             }
  390.  
  391.             continue;
  392.         }
  393.         // world semantics only work with matrices
  394.         else if (ParamDesc.Class != D3DXPC_MATRIX_ROWS && ParamDesc.Class != D3DXPC_MATRIX_COLUMNS)
  395.             continue;
  396.  
  397.         if (lstrcmpi("worldview", ParamDesc.Semantic) == 0)
  398.         {
  399.             pEffectInfo->iWorldView = hParam;
  400.         }
  401.         else if (lstrcmpi("WorldViewProjection", ParamDesc.Semantic) == 0)
  402.         {
  403.             pEffectInfo->iWorldViewProjection = hParam;
  404.         }
  405.         else if (lstrcmpi("View", ParamDesc.Semantic) == 0)
  406.         {
  407.             pEffectInfo->iView = hParam;
  408.         }
  409.         else if (lstrcmpi("ViewProjection", ParamDesc.Semantic) == 0)
  410.         {
  411.             pEffectInfo->iViewProjection = hParam;
  412.         }
  413.         else if (lstrcmpi("Projection", ParamDesc.Semantic) == 0)
  414.         {
  415.             pEffectInfo->iProjection = hParam;
  416.         }
  417.         else if (lstrcmpi("WorldArray", ParamDesc.Semantic) == 0)
  418.         {
  419.             pEffectInfo->iWorld1 = hParam;
  420.             pEffectInfo->cWorlds = ParamDesc.Elements;
  421.         }
  422.         else if (lstrcmpi("WorldInvTransArray", ParamDesc.Semantic) == 0)
  423.         {
  424.             pEffectInfo->iWorldInvTrans1 = hParam;
  425.             pEffectInfo->cWorldInvTrans = ParamDesc.Elements;
  426.         }
  427.     }
  428.  
  429.  
  430. e_Exit:
  431.     return hr;
  432. }
  433.  
  434. HRESULT
  435. SetEffectMatrices
  436.     (
  437.     LPD3DXEFFECT pEffect, 
  438.     SEffectInfo *pEffectInfo, 
  439.     LPD3DXMATRIX pProjection, 
  440.     LPD3DXMATRIX pView, 
  441.     LPD3DXMATRIX pWorlds, 
  442.     DWORD cWorlds,
  443.     LPD3DXMATRIX pWorldInvTrans, 
  444.     DWORD cWorldInvTrans,
  445.     FLOAT fTime
  446.     )
  447. {
  448.     HRESULT hr = S_OK;
  449.     D3DXMATRIX matTemp;
  450.     UINT iWorld;
  451.  
  452.     if ((pEffect == NULL) || (pEffectInfo == NULL))
  453.     {
  454. #ifdef DBG
  455.         if (pEffectInfo == NULL)
  456.             DPF(0, "D3DXGenerateEffectInfo: pEffectInfo cannot be NULL");
  457.         else if (pEffect == NULL)
  458.             DPF(0, "D3DXGenerateEffectInfo: pEffect cannot be NULL");
  459. #endif
  460.         hr = D3DERR_INVALIDCALL;
  461.         goto e_Exit;
  462.     }
  463.  
  464.     if (pEffectInfo->hTime)
  465.     {
  466.         pEffect->SetFloat(pEffectInfo->hTime, fTime);
  467.     }
  468.  
  469.     // first work out worldview and worldviewprojection
  470.     if ((pEffectInfo->iWorldView != NULL) || (pEffectInfo->iWorldViewProjection != NULL))
  471.     {
  472.         D3DXMatrixMultiply(&matTemp, pWorlds, pView);
  473.  
  474.         if (pEffectInfo->iWorldView != NULL)
  475.         {
  476.             pEffect->SetMatrix(pEffectInfo->iWorldView, &matTemp);
  477.         }
  478.  
  479.         if (pEffectInfo->iWorldViewProjection != NULL)
  480.         {
  481.             D3DXMatrixMultiply(&matTemp, &matTemp, pProjection);
  482.             pEffect->SetMatrix(pEffectInfo->iWorldViewProjection, &matTemp);
  483.         }
  484.     }
  485.  
  486.     // add the view and projection matrices if used
  487.     if (pEffectInfo->iProjection != NULL)
  488.     {
  489.         pEffect->SetMatrix(pEffectInfo->iProjection, pProjection);
  490.     }
  491.  
  492.     if (pEffectInfo->iView != NULL)
  493.     {
  494.         pEffect->SetMatrix(pEffectInfo->iView, pView);
  495.     }
  496.  
  497.     // generate the view projection if used
  498.     if (pEffectInfo->iViewProjection != NULL)
  499.     {
  500.         D3DXMatrixMultiply(&matTemp, pView, pProjection);
  501.         pEffect->SetMatrix(pEffectInfo->iViewProjection, &matTemp);
  502.     }
  503.  
  504.     // set all world matrices used
  505.     if (pEffectInfo->cWorlds > 0)
  506.     {
  507.         if (pEffectInfo->cWorlds > cWorlds)
  508.         {
  509.             DPF(0, "More worlds in effect file than specified in pWorlds");
  510.             hr = D3DERR_INVALIDCALL;
  511.             goto e_Exit;
  512.         }
  513.  
  514.         // if indices can be used, use them
  515.         if (pEffectInfo->iWorld1 != NULL)
  516.         {
  517.             pEffect->SetMatrixArray(pEffectInfo->iWorld1, pWorlds, min(cWorlds, pEffectInfo->cWorlds));
  518.         }
  519.     }
  520.  
  521.     // set all world inverse matrices used
  522.     if (pEffectInfo->cWorldInvTrans > 0)
  523.     {
  524.         if ((cWorldInvTrans == NULL) && (cWorlds > 0))
  525.         {
  526.             pWorldInvTrans = (LPD3DXMATRIX)_alloca(sizeof(D3DXMATRIX) * cWorlds);
  527.             cWorldInvTrans = cWorlds;
  528.  
  529.             for (iWorld = 0; iWorld < cWorlds; iWorld++)
  530.             {
  531.                 D3DXMatrixInverse(pWorldInvTrans + iWorld, NULL, pWorlds + iWorld);
  532.                 D3DXMatrixTranspose(pWorldInvTrans, pWorldInvTrans);
  533.             }
  534.         }
  535.  
  536.         if (pEffectInfo->cWorldInvTrans > cWorldInvTrans)
  537.         {
  538.             DPF(0, "D3DX:  More worlds in effect file than specified in pWorldInvTrans");
  539.             hr = D3DERR_INVALIDCALL;
  540.             goto e_Exit;
  541.         }
  542.  
  543.         // if indices can be used, use them
  544.         if (pEffectInfo->iWorldInvTrans1 != NULL)
  545.         {
  546.             pEffect->SetMatrixArray(pEffectInfo->iWorldInvTrans1, pWorldInvTrans, min(cWorlds, pEffectInfo->cWorldInvTrans));
  547.         }
  548.     }
  549.  
  550.  
  551. e_Exit:
  552.     return hr;
  553. }
  554.  
  555. //============================================================================================================
  556. //   UNDONE UNDONE The following "function" still needs work.  Needs some sort of filename resolver
  557. //============================================================================================================
  558.  
  559. //-----------------------------------------------------------------------------
  560. // Name: DXUtil_GetDXSDKMediaPath()
  561. // Desc: Returns the DirectX SDK media path
  562. //-----------------------------------------------------------------------------
  563. const TCHAR* DXUtil_GetDXSDKMediaPath()
  564. {
  565.     static TCHAR strNull[2] = _T("");
  566.     static TCHAR strPath[MAX_PATH];
  567.     DWORD dwType;
  568.     DWORD dwSize = MAX_PATH;
  569.     HKEY  hKey;
  570.  
  571.     // Open the appropriate registry key
  572.     LONG lResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  573.                                 _T("Software\\Microsoft\\DirectX SDK"),
  574.                                 0, KEY_READ, &hKey );
  575.     if( ERROR_SUCCESS != lResult )
  576.         return strNull;
  577.  
  578.     lResult = RegQueryValueEx( hKey, _T("DX81SDK Samples Path"), NULL,
  579.                               &dwType, (BYTE*)strPath, &dwSize );
  580.     RegCloseKey( hKey );
  581.  
  582.     if( ERROR_SUCCESS != lResult )
  583.         return strNull;
  584.  
  585.     _tcscat( strPath, _T("\\Media\\") );
  586.  
  587.     return strPath;
  588. }
  589.  
  590.  
  591. //-----------------------------------------------------------------------------
  592. // Name: DXUtil_FindMediaFile()
  593. // Desc: Returns a valid path to a DXSDK media file
  594. //-----------------------------------------------------------------------------
  595. HRESULT DXUtil_FindMediaFile( TCHAR* strPath, TCHAR* strFilename )
  596. {
  597.     HANDLE file;
  598.     TCHAR strFullPath[1024];
  599.     TCHAR *strShortName;
  600.     DWORD cchPath;
  601.  
  602.     if( NULL==strFilename || NULL==strPath )
  603.         return E_INVALIDARG;
  604.  
  605.     // Build full path name from strFileName (strShortName will be just the leaf filename)
  606.     cchPath = GetFullPathName(strFilename, sizeof(strFullPath)/sizeof(TCHAR), strFullPath, &strShortName);
  607.     if ((cchPath == 0) || (sizeof(strFullPath)/sizeof(TCHAR) <= cchPath))
  608.         return E_FAIL;
  609.  
  610.     // first try to find the filename given a full path
  611.     file = CreateFile( strFullPath, GENERIC_READ, FILE_SHARE_READ, NULL, 
  612.                        OPEN_EXISTING, 0, NULL );
  613.     if( INVALID_HANDLE_VALUE != file )
  614.     {
  615.         _tcscpy( strPath, strFullPath );
  616.         CloseHandle( file );
  617.         return S_OK;
  618.     }
  619.     
  620.     // next try to find the filename in the current working directory (path stripped)
  621.     file = CreateFile( strShortName, GENERIC_READ, FILE_SHARE_READ, NULL, 
  622.                        OPEN_EXISTING, 0, NULL );
  623.     if( INVALID_HANDLE_VALUE != file )
  624.     {
  625.         _tcscpy( strPath, strShortName );
  626.         CloseHandle( file );
  627.         return S_OK;
  628.     }
  629.     
  630.     // last, check if the file exists in the media directory
  631.     _stprintf( strPath, _T("%s%s"), DXUtil_GetDXSDKMediaPath(), strShortName );
  632.  
  633.     file = CreateFile( strPath, GENERIC_READ, FILE_SHARE_READ, NULL, 
  634.                        OPEN_EXISTING, 0, NULL );
  635.     if( INVALID_HANDLE_VALUE != file )
  636.     {
  637.         CloseHandle( file );
  638.         return S_OK;
  639.     }
  640.  
  641.     // On failure, just return the file as the path
  642.     _tcscpy( strPath, strFilename );
  643.     return E_FAIL;
  644. }
  645.  
  646. HRESULT WINAPI D3DXCreateEffectInstance
  647.     (
  648.     CONST D3DXEFFECTINSTANCE *pEffectInstance, 
  649.     LPDIRECT3DDEVICE9 pDevice, 
  650.     LPD3DXEFFECT *ppEffect, 
  651.     LPD3DXBUFFER *ppCompilationErrors
  652.     )
  653. {
  654.     HRESULT hr = S_OK;
  655.     LPD3DXEFFECT pEffect = NULL;
  656.     UINT iDefault;
  657.     LPD3DXEFFECTDEFAULT pDefault;
  658.     LPDIRECT3DBASETEXTURE9 pTex;
  659.     D3DXEFFECT_DESC EffectDesc;
  660.     D3DXPARAMETER_DESC ParamDesc;
  661.     D3DXPARAMETER_DESC AnnotDesc;
  662.     LPCTSTR pTextureFilename;
  663.  
  664.     if ((pEffectInstance == NULL) || (pDevice == NULL) || (ppEffect == NULL))
  665.     {
  666. #ifdef DBG
  667.         if (pEffectInstance == NULL)
  668.             DPF(0, "D3DXCreateEffectInstance: pEffectInstance cannot be NULL");
  669.         else if (pDevice == NULL)
  670.             DPF(0, "D3DXCreateEffectInstance: pDevice cannot be NULL");
  671.         else if (ppEffect == NULL)
  672.             DPF(0, "D3DXCreateEffectInstance: ppEffect cannot be NULL");
  673. #endif
  674.         hr = D3DERR_INVALIDCALL;
  675.         goto e_Exit;
  676.     }
  677.  
  678.     // Define DEBUG_VS and/or DEBUG_PS to debug vertex and/or pixel shaders with the shader debugger.  
  679.     // Debugging vertex shaders requires either REF or software vertex processing, and debugging 
  680.     // pixel shaders requires REF.  The D3DXSHADER_FORCE_*_SOFTWARE_NOOPT flag improves the debug 
  681.     // experience in the shader debugger.  It enables source level debugging, prevents instruction 
  682.     // reordering, prevents dead code elimination, and forces the compiler to compile against the next 
  683.     // higher available software target, which ensures that the unoptimized shaders do not exceed 
  684.     // the shader model limitations.  Setting these flags will cause slower rendering since the shaders 
  685.     // will be unoptimized and forced into software.  See the DirectX documentation for more information 
  686.     // about using the shader debugger.
  687.     DWORD dwShaderFlags = 0;
  688.     #ifdef DEBUG_VS
  689.         dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
  690.     #endif
  691.     #ifdef DEBUG_PS
  692.         dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
  693.     #endif
  694.  
  695.     // if file based effect, then load it
  696.     if (pEffectInstance->pEffectFilename != NULL)
  697.     {
  698.         hr = D3DXCreateEffectFromFileA(pDevice, pEffectInstance->pEffectFilename, NULL, NULL, dwShaderFlags, NULL, &pEffect, ppCompilationErrors);
  699.         if (FAILED(hr))
  700.             goto e_Exit;
  701.     }
  702.     else  // generate the default effect AKA texture1.fx
  703.     {
  704.         hr = D3DXCreateEffectFromResource(pDevice, NULL, MAKEINTRESOURCE(IDD_TEXTURE1), NULL, NULL, dwShaderFlags, NULL, &pEffect, ppCompilationErrors);
  705.         if (FAILED(hr))
  706.             return hr;
  707.     }
  708.  
  709.     for (iDefault = 0; iDefault < pEffectInstance->NumDefaults; iDefault++)
  710.     {
  711.         D3DXPARAMETER_DESC ParamDesc;
  712.  
  713.         pDefault = &pEffectInstance->pDefaults[iDefault];
  714.         switch (pDefault->Type)
  715.         {
  716.             case D3DXEDT_STRING:
  717.  
  718.                 hr = pEffect->SetString(pDefault->pParamName, (char*)pDefault->pValue);
  719.                 if (FAILED(hr))
  720.                 {
  721.                     // handle the currently broken Name case... if setting a string to an interface type, add the @Name
  722.                     hr = pEffect->GetParameterDesc(pDefault->pParamName, &ParamDesc);
  723.                     if (SUCCEEDED(hr))
  724.                     {
  725.                         if ((ParamDesc.Type >= D3DXPT_TEXTURE) || (ParamDesc.Type <= D3DXPT_PIXELSHADER))
  726.                         {
  727.                             char szBuf[1024];
  728.                             sprintf(szBuf, "%s%s", pDefault->pParamName, "@Name");
  729.                             pEffect->SetString(szBuf, (char*)pDefault->pValue);
  730.                         }
  731.                     }
  732.                 }
  733.  
  734.                 break;
  735.             case D3DXEDT_FLOATS:
  736.                 switch (pDefault->NumBytes / 4)
  737.                 {
  738.                 case 1:
  739.                     pEffect->SetFloat(pDefault->pParamName, *(FLOAT*)pDefault->pValue);
  740.                     break;
  741.                 case 4:
  742.                     pEffect->SetVector(pDefault->pParamName, (LPD3DXVECTOR4)pDefault->pValue);
  743.                     break;
  744.                 case 16:
  745.                     pEffect->SetMatrix(pDefault->pParamName, (LPD3DXMATRIX)pDefault->pValue);
  746.                     break;
  747.                 default:
  748.                     DPF(0, "D3DXCreateEffectInstance: Unknown number of floats specified on parameter: %s  (Skipping)", pDefault->pParamName);
  749.                     break;
  750.                 }
  751.                 break;
  752.             case D3DXEDT_DWORD:
  753.                 pEffect->SetInt(pDefault->pParamName, (INT)*(DWORD*)pDefault->pValue);
  754.                 break;
  755.         }
  756.     }
  757.  
  758.     pEffect->GetDesc(&EffectDesc);
  759.  
  760.     for(UINT iParam = 0; iParam < EffectDesc.Parameters; iParam++)
  761.     {
  762.         CHAR szBuf[1024];
  763.         D3DXHANDLE hParam, hAnnot;
  764.  
  765.         LPCSTR pstrName = NULL;
  766.         LPCSTR pstrFunction = NULL;
  767.         LPCSTR pstrTarget = NULL;
  768.         LPCSTR pstrTextureType = NULL;
  769.         INT Width = D3DX_DEFAULT;
  770.         INT Height= D3DX_DEFAULT;
  771.         INT Depth = D3DX_DEFAULT;
  772.  
  773.  
  774.  
  775.         hParam = pEffect->GetParameter(NULL, iParam);
  776.         
  777.         pEffect->GetParameterDesc(hParam, &ParamDesc);
  778.  
  779.         // only load textures
  780.         if (D3DXPT_TEXTURE != ParamDesc.Type) 
  781.             continue;
  782.         
  783.         for( UINT iAnnot = 0; iAnnot < ParamDesc.Annotations; iAnnot++ )
  784.         {
  785.             hAnnot = pEffect->GetAnnotation ( hParam, iAnnot );
  786.             pEffect->GetParameterDesc( hAnnot, &AnnotDesc );
  787.             if( lstrcmpi( AnnotDesc.Name, "name" ) == 0 )
  788.                 pEffect->GetString( hAnnot, &pstrName );
  789.             else if ( lstrcmpi( AnnotDesc.Name, "function" ) == 0 )
  790.                 pEffect->GetString( hAnnot, &pstrFunction );
  791.             else if ( lstrcmpi( AnnotDesc.Name, "target" ) == 0 )
  792.                 pEffect->GetString( hAnnot, &pstrTarget );
  793.             else if ( lstrcmpi( AnnotDesc.Name, "width" ) == 0 )
  794.                 pEffect->GetInt( hAnnot, &Width );
  795.             else if ( lstrcmpi( AnnotDesc.Name, "height" ) == 0 )
  796.                 pEffect->GetInt( hAnnot, &Height );
  797.             else if ( lstrcmpi( AnnotDesc.Name, "depth" ) == 0 )
  798.                 pEffect->GetInt( hAnnot, &Depth );
  799.             else if( lstrcmpi( AnnotDesc.Name, "type" ) == 0 )
  800.                 pEffect->GetString( hAnnot, &pstrTextureType );
  801.  
  802.         }
  803.  
  804.         if (pstrName != NULL)
  805.         {
  806.             TCHAR strTexturePath[512] = _T("");
  807.             DXUtil_FindMediaFile( strTexturePath, (TCHAR*)pstrName );
  808.  
  809.             if (pstrTextureType != NULL) 
  810.             {
  811.                 if( lstrcmpi( pstrTextureType, "volume" ) == 0 )
  812.                 {
  813.                     LPDIRECT3DVOLUMETEXTURE9 pVolumeTex = NULL;
  814.                     if( SUCCEEDED( hr = D3DXCreateVolumeTextureFromFileEx( pDevice, strTexturePath, 
  815.                         Width, Height, Depth, 1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
  816.                         D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &pVolumeTex ) ) )
  817.                     {
  818.                         pTex = pVolumeTex;
  819.                     }
  820.                 }
  821.                 else if( lstrcmpi( pstrTextureType, "cube" ) == 0 )
  822.                 {
  823.                     LPDIRECT3DCUBETEXTURE9 pCubeTex = NULL;
  824.                     if( SUCCEEDED( hr = D3DXCreateCubeTextureFromFileEx( pDevice, strTexturePath, 
  825.                         Width, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
  826.                         D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &pCubeTex ) ) )
  827.                     {
  828.                         pTex = pCubeTex;
  829.                     }
  830.                 }
  831.             }
  832.             else
  833.             {
  834.                 LPDIRECT3DTEXTURE9 p2DTex = NULL;
  835.                 if( SUCCEEDED( hr = D3DXCreateTextureFromFileEx( pDevice, strTexturePath, 
  836.                     Width, Height, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
  837.                     D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, &p2DTex ) ) )
  838.                 {
  839.                     pTex = p2DTex;
  840.                 }
  841.             }
  842.  
  843.             if (FAILED(hr) || (pTex == NULL))
  844.                 hr = S_OK;
  845.             else
  846.             {
  847.                 pEffect->SetTexture( hParam, pTex );
  848.                 GXRELEASE( pTex );
  849.             }
  850.         }
  851.         else if( pstrFunction != NULL )
  852.         {
  853.             LPD3DXBUFFER pFunction = NULL;
  854.             LPD3DXTEXTURESHADER pTextureShader = NULL;
  855.  
  856.             if( pstrTarget == NULL )
  857.                 pstrTarget = "tx_1_0";
  858.     
  859.             if( SUCCEEDED( hr = D3DXCompileShaderFromFile( pEffectInstance->pEffectFilename, NULL, 
  860.                 NULL, pstrFunction, pstrTarget, 0, &pFunction, NULL, NULL ) ) )
  861.             {
  862.                 if( SUCCEEDED( hr = D3DXCreateTextureShader( (DWORD *)pFunction->GetBufferPointer(), &pTextureShader ) ) )
  863.                 {
  864.                     if( Width == D3DX_DEFAULT )
  865.                         Width = 64;
  866.                     if( Height == D3DX_DEFAULT )
  867.                         Height = 64;
  868.                     if( Depth == D3DX_DEFAULT )
  869.                         Depth = 64;
  870.  
  871.                     if (pstrTextureType != NULL) 
  872.                     {
  873.                         if( lstrcmpi( pstrTextureType, "volume" ) == 0 )
  874.                         {
  875.                             LPDIRECT3DVOLUMETEXTURE9 pVolumeTex = NULL;
  876.                             if( SUCCEEDED( hr = D3DXCreateVolumeTexture( pDevice, 
  877.                                 Width, Height, Depth, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pVolumeTex) ) )
  878.                             {
  879.                                 if( SUCCEEDED( hr = D3DXFillVolumeTextureTX( pVolumeTex, pTextureShader ) ) )
  880.                                     pTex = pVolumeTex;
  881.                             }
  882.                         }
  883.                         else if( lstrcmpi( pstrTextureType, "cube" ) == 0 )
  884.                         {
  885.                             LPDIRECT3DCUBETEXTURE9 pCubeTex = NULL;
  886.                             if( SUCCEEDED( hr = D3DXCreateCubeTexture( pDevice, 
  887.                                 Width, D3DX_DEFAULT, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pCubeTex) ) )
  888.                             {
  889.                                 if( SUCCEEDED( hr = D3DXFillCubeTextureTX( pCubeTex, pTextureShader ) ) )
  890.                                     pTex = pCubeTex;
  891.                             }
  892.                         }
  893.                     }
  894.                     else
  895.                     {
  896.                         LPDIRECT3DTEXTURE9 p2DTex = NULL;
  897.                         if( SUCCEEDED( hr = D3DXCreateTexture( pDevice, Width, Height, 
  898.                             D3DX_DEFAULT, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &p2DTex) ) )
  899.                         {
  900.                             if( SUCCEEDED( hr = D3DXFillTextureTX( p2DTex, pTextureShader ) ) )
  901.                                 pTex = p2DTex;
  902.                         }
  903.                     }
  904.                     pEffect->SetTexture( hParam, pTex );
  905.                     GXRELEASE(pTex);
  906.                     GXRELEASE(pTextureShader);
  907.                 }
  908.                 GXRELEASE(pFunction);
  909.             }
  910.         }
  911.     }
  912.  
  913.  
  914.     *ppEffect = pEffect;
  915.     pEffect = NULL;
  916. e_Exit:
  917.     GXRELEASE(pEffect);
  918.     return hr;
  919. }
  920.  
  921. //-----------------------------------------------------------------------------
  922. // Name: D3DUtil_InitLight()
  923. // Desc: Initializes a D3DLIGHT structure, setting the light position. The
  924. //       diffuse color is set to white; specular and ambient are left as black.
  925. //-----------------------------------------------------------------------------
  926. VOID D3DUtil_InitLight( D3DLIGHT9& light, D3DLIGHTTYPE ltType,
  927.                         FLOAT x, FLOAT y, FLOAT z )
  928. {
  929.     ZeroMemory( &light, sizeof(D3DLIGHT9) );
  930.     light.Type        = ltType;
  931.     light.Diffuse.r   = 1.0f;
  932.     light.Diffuse.g   = 1.0f;
  933.     light.Diffuse.b   = 1.0f;
  934.     D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &D3DXVECTOR3(x, y, z) );
  935.     light.Position.x   = x;
  936.     light.Position.y   = y;
  937.     light.Position.z   = z;
  938.     light.Range        = 1000.0f;
  939. }
  940.  
  941.