home *** CD-ROM | disk | FTP | other *** search
/ Game Programming - All in One (3rd Edition) / game_prog_all_in_one_3rd_ed.iso / DirectX / DX8 Fix / d3dx8_0b.exe / mdraw.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-12  |  15.3 KB  |  481 lines

  1. //-----------------------------------------------------------------------------
  2. // File: mdraw.cpp
  3. //
  4. // Copyright (c) 1999-2001 Microsoft Corporation. All rights reserved.
  5. //-----------------------------------------------------------------------------
  6.  
  7. #include <d3d8.h>
  8. #include <d3dx8.h>
  9. #include "D3DApp.h"
  10. #include "D3DFont.h"
  11. #include "D3DUtil.h"
  12. #include "DXUtil.h"
  13. #include "SkinnedMesh.h"
  14.  
  15.  
  16. HRESULT CMyD3DApplication::DrawMeshContainer(SMeshContainer *pmcMesh)
  17. {
  18.     UINT ipattr;
  19.     HRESULT hr = S_OK;
  20.     LPD3DXBONECOMBINATION pBoneComb;
  21.  
  22.     if (pmcMesh->m_pSkinMesh)
  23.     {
  24.         if (m_method != pmcMesh->m_Method)
  25.         {
  26.             GenerateMesh(pmcMesh);
  27.         }
  28.  
  29.         if (m_method == D3DNONINDEXED)
  30.         {
  31.             pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>(pmcMesh->m_pBoneCombinationBuf->GetBufferPointer());
  32.             // Draw using default vtx processing of the device (typically HW)
  33.             for (ipattr = 0; ipattr < pmcMesh->iAttrSplit; ipattr++)
  34.             {
  35.                 DWORD numBlend = 0;
  36.                 for (DWORD i = 0; i < pmcMesh->m_maxFaceInfl; ++i)
  37.                 {
  38.                     DWORD matid = pBoneComb[ipattr].BoneId[i];
  39.                     if (matid != UINT_MAX)
  40.                     {
  41.                         if (ipattr == 0 || matid != pBoneComb[ipattr - 1].BoneId[i])
  42.                         {
  43.                             m_pd3dDevice->SetTransform(D3DTS_WORLDMATRIX(i), pmcMesh->m_pBoneMatrix[matid]);
  44.                             m_pd3dDevice->MultiplyTransform(D3DTS_WORLDMATRIX(i), &pmcMesh->m_pBoneOffsetMat[matid]);
  45.                         }
  46.                         numBlend = i;
  47.                     }
  48.                 }
  49.  
  50.                 m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, numBlend);
  51.  
  52.                 if (ipattr == 0 || (pBoneComb[ipattr].AttribId != pBoneComb[ipattr - 1].AttribId))
  53.                 {
  54.                     m_pd3dDevice->SetMaterial(&(pmcMesh->rgMaterials[pBoneComb[ipattr].AttribId]));
  55.                     m_pd3dDevice->SetTexture(0, pmcMesh->pTextures[pBoneComb[ipattr].AttribId]);
  56.                 }
  57.  
  58.                 hr = pmcMesh->pMesh->DrawSubset( ipattr );
  59.                 if(FAILED(hr))
  60.                     return hr;
  61.             }
  62.  
  63.             // If necessary, draw parts that HW could not handle using SW
  64.             if (pmcMesh->pMeshSW != NULL)
  65.             {
  66.                 m_pd3dDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, TRUE);
  67.                 for (ipattr = pmcMesh->iAttrSplit; ipattr < pmcMesh->cpattr; ipattr++)
  68.                 {
  69.                     DWORD numBlend = 0;
  70.                     for (DWORD i = 0; i < pmcMesh->m_maxFaceInfl; ++i)
  71.                     {
  72.                         DWORD matid = pBoneComb[ipattr].BoneId[i];
  73.                         if (matid != UINT_MAX)
  74.                         {
  75.                             if (ipattr == pmcMesh->iAttrSplit || (matid != pBoneComb[ipattr - 1].BoneId[i]))
  76.                             {
  77.                                 m_pd3dDevice->SetTransform(D3DTS_WORLDMATRIX(i), pmcMesh->m_pBoneMatrix[matid]);
  78.                                 m_pd3dDevice->MultiplyTransform(D3DTS_WORLDMATRIX(i), &pmcMesh->m_pBoneOffsetMat[matid]);
  79.                             }
  80.                             numBlend = i;
  81.                         }
  82.                     }
  83.  
  84.                     m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, numBlend);
  85.  
  86.                     if (ipattr == pmcMesh->iAttrSplit || (pBoneComb[ipattr].AttribId != pBoneComb[ipattr - 1].AttribId))
  87.                     {
  88.                         m_pd3dDevice->SetMaterial(&(pmcMesh->rgMaterials[pBoneComb[ipattr].AttribId]));
  89.                         m_pd3dDevice->SetTexture(0, pmcMesh->pTextures[pBoneComb[ipattr].AttribId]);
  90.                     }
  91.  
  92.                     hr = pmcMesh->pMeshSW->DrawSubset( ipattr );
  93.                     if(FAILED(hr))
  94.                         return hr;
  95.                 }
  96.                 m_pd3dDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
  97.             }
  98.             m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);
  99.         }
  100.         else if (m_method == D3DINDEXED)
  101.         {
  102.             if (pmcMesh->m_bUseSW)
  103.             {
  104.                 m_pd3dDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, TRUE);
  105.             }
  106.  
  107.             if (pmcMesh->m_maxFaceInfl == 1)
  108.                 m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_0WEIGHTS);
  109.             else
  110.                 m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, pmcMesh->m_maxFaceInfl - 1);
  111.             if (pmcMesh->m_maxFaceInfl)
  112.                 m_pd3dDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, TRUE);
  113.             pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>(pmcMesh->m_pBoneCombinationBuf->GetBufferPointer());
  114.             for (ipattr = 0; ipattr < pmcMesh->cpattr; ipattr++)
  115.             {
  116.                 for (DWORD i = 0; i < pmcMesh->m_paletteSize; ++i)
  117.                 {
  118.                     DWORD matid = pBoneComb[ipattr].BoneId[i];
  119.                     if (matid != UINT_MAX)
  120.                     {
  121.                         m_pd3dDevice->SetTransform(D3DTS_WORLDMATRIX(i), pmcMesh->m_pBoneMatrix[matid]);
  122.                         m_pd3dDevice->MultiplyTransform(D3DTS_WORLDMATRIX(i), &pmcMesh->m_pBoneOffsetMat[matid]);
  123.                     }
  124.                 }
  125.                 
  126.                 m_pd3dDevice->SetMaterial(&(pmcMesh->rgMaterials[pBoneComb[ipattr].AttribId]));
  127.                 m_pd3dDevice->SetTexture(0, pmcMesh->pTextures[pBoneComb[ipattr].AttribId]);
  128.  
  129.                 hr = pmcMesh->pMesh->DrawSubset( ipattr );
  130.                 if(FAILED(hr))
  131.                     return hr;
  132.             }
  133.             m_pd3dDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
  134.             m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);
  135.  
  136.             if (pmcMesh->m_bUseSW)
  137.             {
  138.                 m_pd3dDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
  139.             }
  140.         }
  141.         else if (m_method == SOFTWARE)
  142.         {
  143.             D3DXMATRIX  Identity;
  144.             DWORD       cBones  = pmcMesh->m_pSkinMesh->GetNumBones();
  145.  
  146.             // set up bone transforms
  147.             for (DWORD iBone = 0; iBone < cBones; ++iBone)
  148.             {
  149.                 D3DXMatrixMultiply
  150.                 (
  151.                     &m_pBoneMatrices[iBone],                 // output
  152.                     &pmcMesh->m_pBoneOffsetMat[iBone], 
  153.                     pmcMesh->m_pBoneMatrix[iBone]
  154.                 );
  155.             }
  156.  
  157.             // set world transform
  158.             D3DXMatrixIdentity(&Identity);
  159.             hr = m_pd3dDevice->SetTransform(D3DTS_WORLD, &Identity);
  160.             if (FAILED(hr))
  161.                 return hr;
  162.  
  163.             // generate skinned mesh
  164.             hr = pmcMesh->m_pSkinMesh->UpdateSkinnedMesh(m_pBoneMatrices, pmcMesh->pMesh);
  165.             if (FAILED(hr))
  166.                 return hr;
  167.  
  168.             for (ipattr = 0; ipattr < pmcMesh->cpattr; ipattr++)
  169.             {
  170.                 m_pd3dDevice->SetMaterial(&(pmcMesh->rgMaterials[pmcMesh->m_pAttrTable[ipattr].AttribId]));
  171.                 m_pd3dDevice->SetTexture(0, pmcMesh->pTextures[pmcMesh->m_pAttrTable[ipattr].AttribId]);
  172.                 hr  = pmcMesh->pMesh->DrawSubset(pmcMesh->m_pAttrTable[ipattr].AttribId);
  173.                 if (FAILED(hr))
  174.                     return hr;
  175.             }
  176.             return hr;
  177.         }
  178.     }
  179.     else
  180.     {
  181.         for (ipattr = 0; ipattr < pmcMesh->cpattr; ipattr++)
  182.         {
  183.             m_pd3dDevice->SetMaterial(&(pmcMesh->rgMaterials[ipattr]));
  184.             m_pd3dDevice->SetTexture(0, pmcMesh->pTextures[ipattr]);
  185.             hr = pmcMesh->pMesh->DrawSubset( ipattr );
  186.             if(FAILED(hr))
  187.                 return hr;
  188.         }
  189.     }
  190.  
  191.     return S_OK;
  192. }
  193.  
  194.  
  195.  
  196.  
  197. HRESULT CMyD3DApplication::UpdateFrames(SFrame *pframeCur, D3DXMATRIX &matCur)
  198. {
  199.     HRESULT hr = S_OK;
  200.     pframeCur->matCombined = matCur;
  201.     D3DXMatrixMultiply(&pframeCur->matCombined, &pframeCur->matRot, &matCur);
  202.     D3DXMatrixMultiply(&pframeCur->matCombined, &pframeCur->matCombined, &pframeCur->matTrans );
  203.     SFrame *pframeChild = pframeCur->pframeFirstChild;
  204.     while (pframeChild != NULL)
  205.     {
  206.         hr = UpdateFrames(pframeChild, pframeCur->matCombined);
  207.         if (FAILED(hr))
  208.             return hr;
  209.  
  210.         pframeChild = pframeChild->pframeSibling;
  211.     }
  212.     return S_OK;
  213. }
  214.  
  215.  
  216.  
  217.  
  218. HRESULT CMyD3DApplication::DrawFrames(SFrame *pframeCur, UINT &cTriangles)
  219. {
  220.     HRESULT hr = S_OK;
  221.     SMeshContainer *pmcMesh;
  222.     SFrame *pframeChild;
  223.  
  224.     if (pframeCur->pmcMesh != NULL)
  225.     {
  226.         hr = m_pd3dDevice->SetTransform(D3DTS_WORLD, &pframeCur->matCombined);
  227.         if(FAILED(hr))
  228.             return hr;
  229.     }
  230.  
  231.     pmcMesh = pframeCur->pmcMesh;
  232.     while (pmcMesh != NULL)
  233.     {
  234.         hr = DrawMeshContainer(pmcMesh);
  235.         if (FAILED(hr))
  236.             return hr;
  237.  
  238.         cTriangles += pmcMesh->pMesh->GetNumFaces();
  239.  
  240.         pmcMesh = pmcMesh->pmcNext;
  241.     }
  242.  
  243.     pframeChild = pframeCur->pframeFirstChild;
  244.     while (pframeChild != NULL)
  245.     {
  246.         hr = DrawFrames(pframeChild, cTriangles);
  247.         if (FAILED(hr))
  248.             return hr;
  249.  
  250.         pframeChild = pframeChild->pframeSibling;
  251.     }
  252.  
  253.     return S_OK;
  254. }
  255.  
  256.  
  257.  
  258.  
  259. void SFrame::SetTime(float fGlobalTime)
  260. {
  261.     UINT iKey;
  262.     UINT dwp2;
  263.     UINT dwp3;
  264.     D3DXMATRIX matResult;
  265.     D3DXMATRIX matTemp;
  266.     float fTime1;
  267.     float fTime2;
  268.     float fLerpValue;
  269.     D3DXVECTOR3 vScale;
  270.     D3DXVECTOR3 vPos;
  271.     D3DXQUATERNION quat;
  272.     BOOL bAnimate = false;
  273.     float fTime;
  274.  
  275.     if (m_pMatrixKeys )
  276.     {
  277.         fTime = (float)fmod(fGlobalTime, m_pMatrixKeys[m_cMatrixKeys-1].dwTime);
  278.  
  279.         for (iKey = 0 ;iKey < m_cMatrixKeys ; iKey++)
  280.         {
  281.             if ((float)m_pMatrixKeys[iKey].dwTime > fTime)
  282.             {
  283.                 dwp3 = iKey;
  284.  
  285.                 if (iKey > 0)
  286.                 {
  287.                     dwp2= iKey - 1;
  288.                 }
  289.                 else  // when iKey == 0, then dwp2 == 0
  290.                 {
  291.                     dwp2 = iKey;
  292.                 }
  293.  
  294.                 break;
  295.             }
  296.         }
  297.         fTime1 = (float)m_pMatrixKeys[dwp2].dwTime;
  298.         fTime2 = (float)m_pMatrixKeys[dwp3].dwTime;
  299.  
  300.         if ((fTime2 - fTime1) ==0)
  301.             fLerpValue = 0;
  302.         else
  303.             fLerpValue =  (fTime - fTime1)  / (fTime2 - fTime1);
  304.  
  305.         if (fLerpValue > 0.5)
  306.         {
  307.             iKey = dwp3;
  308.         }
  309.         else
  310.         {
  311.             iKey = dwp2;
  312.         }
  313.  
  314.         pframeToAnimate->matRot = m_pMatrixKeys[iKey].mat;
  315.     }
  316.     else
  317.     {
  318.         D3DXMatrixIdentity(&matResult);
  319.  
  320.         if (m_pScaleKeys)
  321.         {
  322.             dwp2 = dwp3 = 0;
  323.  
  324.             fTime = (float)fmod(fGlobalTime, m_pScaleKeys[m_cScaleKeys-1].dwTime);
  325.  
  326.             for (iKey = 0 ;iKey < m_cScaleKeys ; iKey++)
  327.             {
  328.                 if ((float)m_pScaleKeys[iKey].dwTime > fTime)
  329.                 {
  330.                     dwp3 = iKey;
  331.  
  332.                     if (iKey > 0)
  333.                     {
  334.                         dwp2= iKey - 1;
  335.                     }
  336.                     else  // when iKey == 0, then dwp2 == 0
  337.                     {
  338.                         dwp2 = iKey;
  339.                     }
  340.  
  341.                     break;
  342.                 }
  343.             }
  344.             fTime1 = (float)m_pScaleKeys[dwp2].dwTime;
  345.             fTime2 = (float)m_pScaleKeys[dwp3].dwTime;
  346.  
  347.             if ((fTime2 - fTime1) ==0)
  348.                 fLerpValue = 0;
  349.             else
  350.                 fLerpValue =  (fTime - fTime1)  / (fTime2 - fTime1);
  351.  
  352.             D3DXVec3Lerp(&vScale,
  353.                     &m_pScaleKeys[dwp2].vScale,
  354.                     &m_pScaleKeys[dwp3].vScale,
  355.                     fLerpValue);
  356.  
  357.  
  358.             D3DXMatrixScaling(&matTemp, vScale.x, vScale.y, vScale.z);
  359.  
  360.             D3DXMatrixMultiply(&matResult, &matResult, &matTemp);
  361.  
  362.             bAnimate = true;
  363.         }
  364.  
  365.         //check rot keys
  366.         if (m_pRotateKeys )
  367.         {
  368.             dwp2 = dwp3 = 0;
  369.  
  370.             fTime = (float)fmod(fGlobalTime, m_pRotateKeys[m_cRotateKeys-1].dwTime);
  371.  
  372.             for (iKey = 0 ;iKey < m_cRotateKeys ; iKey++)
  373.             {
  374.                 if ((float)m_pRotateKeys[iKey].dwTime > fTime)
  375.                 {
  376.                     dwp3 = iKey;
  377.  
  378.                     if (iKey > 0)
  379.                     {
  380.                         dwp2= iKey - 1;
  381.                     }
  382.                     else  // when iKey == 0, then dwp2 == 0
  383.                     {
  384.                         dwp2 = iKey;
  385.                     }
  386.  
  387.                     break;
  388.                 }
  389.             }
  390.             fTime1 = (float)m_pRotateKeys[dwp2].dwTime;
  391.             fTime2 = (float)m_pRotateKeys[dwp3].dwTime;
  392.  
  393.             if ((fTime2 - fTime1) ==0)
  394.                 fLerpValue = 0;
  395.             else
  396.                 fLerpValue =  (fTime - fTime1)  / (fTime2 - fTime1);
  397.  
  398.             //s=0;
  399.             D3DXQUATERNION q1,q2;
  400.             q1.x =-m_pRotateKeys[dwp2].quatRotate.x;
  401.             q1.y =-m_pRotateKeys[dwp2].quatRotate.y;
  402.             q1.z =-m_pRotateKeys[dwp2].quatRotate.z;
  403.             q1.w =m_pRotateKeys[dwp2].quatRotate.w;
  404.  
  405.             q2.x =-m_pRotateKeys[dwp3].quatRotate.x;
  406.             q2.y =-m_pRotateKeys[dwp3].quatRotate.y;
  407.             q2.z =-m_pRotateKeys[dwp3].quatRotate.z;
  408.             q2.w =m_pRotateKeys[dwp3].quatRotate.w;
  409.  
  410.             D3DXQuaternionSlerp(&quat,
  411.                                 &q1,
  412.                                 &q2,
  413.                                 fLerpValue);
  414.  
  415.             D3DXMatrixRotationQuaternion(&matTemp, &quat);
  416.  
  417.             D3DXMatrixMultiply(&matResult, &matResult, &matTemp);
  418.             bAnimate = true;
  419.         }
  420.  
  421.         if (m_pPositionKeys)
  422.         {
  423.             dwp2=dwp3=0;
  424.  
  425.             fTime = (float)fmod(fGlobalTime, m_pPositionKeys[m_cRotateKeys-1].dwTime);
  426.  
  427.             for (iKey = 0 ;iKey < m_cPositionKeys ; iKey++)
  428.             {
  429.                 if ((float)m_pPositionKeys[iKey].dwTime > fTime)
  430.                 {
  431.                     dwp3 = iKey;
  432.  
  433.                     if (iKey > 0)
  434.                     {
  435.                         dwp2= iKey - 1;
  436.                     }
  437.                     else  // when iKey == 0, then dwp2 == 0
  438.                     {
  439.                         dwp2 = iKey;
  440.                     }
  441.  
  442.                     break;
  443.                 }
  444.             }
  445.             fTime1 = (float)m_pPositionKeys[dwp2].dwTime;
  446.             fTime2 = (float)m_pPositionKeys[dwp3].dwTime;
  447.  
  448.             if ((fTime2 - fTime1) ==0)
  449.                 fLerpValue = 0;
  450.             else
  451.                 fLerpValue =  (fTime - fTime1)  / (fTime2 - fTime1);
  452.  
  453.  
  454.             D3DXVec3Lerp((D3DXVECTOR3*)&vPos,
  455.                     &m_pPositionKeys[dwp2].vPos,
  456.                     &m_pPositionKeys[dwp3].vPos,
  457.                     fLerpValue);
  458.  
  459.             D3DXMatrixTranslation(&matTemp, vPos.x, vPos.y, vPos.z);
  460.  
  461.             D3DXMatrixMultiply(&matResult, &matResult, &matTemp);
  462.             bAnimate = true;
  463.         }
  464.         else
  465.         {
  466.             D3DXMatrixTranslation(&matTemp, pframeToAnimate->matRotOrig._41, pframeToAnimate->matRotOrig._42, pframeToAnimate->matRotOrig._43);
  467.  
  468.             D3DXMatrixMultiply(&matResult, &matResult, &matTemp);
  469.         }
  470.  
  471.         if (bAnimate)
  472.         {
  473.             pframeToAnimate->matRot = matResult;
  474.         }
  475.     }
  476. }
  477.  
  478.  
  479.  
  480.  
  481.