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

📄 skinnedmesh.h

📁 我们数据结构课的课程设计
💻 H
📖 第 1 页 / 共 4 页
字号:
                D3DXCOLOR ambEmm;
                D3DXColorModulate(&ambEmm, &color1, &color2);
                ambEmm += D3DXCOLOR(pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D.Emissive);

                // set material color properties 
                m_pEffect->SetVector("MaterialDiffuse", (D3DXVECTOR4*)&(pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D.Diffuse));
                m_pEffect->SetVector("MaterialAmbient", (D3DXVECTOR4*)&ambEmm);

                // setup the material of the mesh subset - REMEMBER to use the original pre-skinning attribute id to get the correct material id
                Device->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] );

                // Set CurNumBones to select the correct vertex shader for the number of bones
                m_pEffect->SetInt( "CurNumBones", pMeshContainer->NumInfl -1);

                // Start the effect now all parameters have been updated
                UINT numPasses;
                m_pEffect->Begin( &numPasses, D3DXFX_DONOTSAVESTATE );
                for( UINT iPass = 0; iPass < numPasses; iPass++ )
                {
                    m_pEffect->Pass( iPass );
                    // draw the subset with the current world matrix palette and material state
                    pMeshContainer->MeshData.pMesh->DrawSubset( iAttrib );
                }

                m_pEffect->End();        

                Device->SetVertexShader(NULL);
            }

            // remember to reset back to hw vertex processing if software was required
            if (pMeshContainer->UseSoftwareVP)
            {
                Device->SetSoftwareVertexProcessing(FALSE);
            }
        }
        else if (m_SkinningMethod == SOFTWARE)
        {
            D3DXMATRIX  Identity;
            DWORD       cBones  = pMeshContainer->pSkinInfo->GetNumBones();
            DWORD       iBone;
            PBYTE       pbVerticesSrc;
            PBYTE       pbVerticesDest;

            // set up bone transforms
            for (iBone = 0; iBone < cBones; ++iBone)
            {
                D3DXMatrixMultiply
                (
                    &m_pBoneMatrices[iBone],                 // output
                    &pMeshContainer->pBoneOffsetMatrices[iBone], 
                    pMeshContainer->ppBoneMatrixPtrs[iBone]
                );
            }

            // set world transform
            D3DXMatrixIdentity(&Identity);
            Device->SetTransform(D3DTS_WORLD, &Identity);

            pMeshContainer->pOrigMesh->LockVertexBuffer(D3DLOCK_READONLY, (LPVOID*)&pbVerticesSrc);
            pMeshContainer->MeshData.pMesh->LockVertexBuffer(0, (LPVOID*)&pbVerticesDest);

            // generate skinned mesh
            pMeshContainer->pSkinInfo->UpdateSkinnedMesh(m_pBoneMatrices, NULL, pbVerticesSrc, pbVerticesDest);

            pMeshContainer->pOrigMesh->UnlockVertexBuffer();
            pMeshContainer->MeshData.pMesh->UnlockVertexBuffer();

            for (iAttrib = 0; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++)
            {
                Device->SetMaterial(&(pMeshContainer->pMaterials[pMeshContainer->pAttributeTable[iAttrib].AttribId].MatD3D));
                Device->SetTexture(0, pMeshContainer->ppTextures[pMeshContainer->pAttributeTable[iAttrib].AttribId]);
                pMeshContainer->MeshData.pMesh->DrawSubset(pMeshContainer->pAttributeTable[iAttrib].AttribId);
            }
        }
        else // bug out as unsupported mode
        {
            return;
        }
    }
    else  // standard mesh, just draw it after setting material properties
    {
        Device->SetTransform(D3DTS_WORLD, &pFrame->CombinedTransformationMatrix);

        for (iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; iMaterial++)
        {
            Device->SetMaterial( &pMeshContainer->pMaterials[iMaterial].MatD3D );
            Device->SetTexture( 0, pMeshContainer->ppTextures[iMaterial] );
            pMeshContainer->MeshData.pMesh->DrawSubset(iMaterial);
        }
    }
}

//-----------------------------------------------------------------------------
// Name: DrawFrame()
// Desc: Called to render a frame in the hierarchy
//-----------------------------------------------------------------------------
void DrawFrame(LPD3DXFRAME pFrame)
{
    LPD3DXMESHCONTAINER pMeshContainer;

    pMeshContainer = pFrame->pMeshContainer;
    while (pMeshContainer != NULL)
    {
        DrawMeshContainer(pMeshContainer, pFrame);

        pMeshContainer = pMeshContainer->pNextMeshContainer;
    }

    if (pFrame->pFrameSibling != NULL)
    {
        DrawFrame(pFrame->pFrameSibling);
    }

    if (pFrame->pFrameFirstChild != NULL)
    {
        DrawFrame(pFrame->pFrameFirstChild);
    }
}

//-----------------------------------------------------------------------------
// Name: DrawFrame()
// Desc: Called to render a frame in the hierarchy
//-----------------------------------------------------------------------------
void UpdateSkinningMethod(LPD3DXFRAME pFrameBase)
{
    D3DXFRAME_DERIVED *pFrame = (D3DXFRAME_DERIVED*)pFrameBase;
    D3DXMESHCONTAINER_DERIVED *pMeshContainer;

    pMeshContainer = (D3DXMESHCONTAINER_DERIVED *)pFrame->pMeshContainer;

    while (pMeshContainer != NULL)
    {
        GenerateSkinnedMesh(pMeshContainer);

        pMeshContainer = (D3DXMESHCONTAINER_DERIVED *)pMeshContainer->pNextMeshContainer;
    }

    if (pFrame->pFrameSibling != NULL)
    {
        UpdateSkinningMethod(pFrame->pFrameSibling);
    }

    if (pFrame->pFrameFirstChild != NULL)
    {
        UpdateSkinningMethod(pFrame->pFrameFirstChild);
    }
}

HRESULT ConfirmDevice (D3DCAPS9* pCaps, DWORD dwBehavior, 
                                          D3DFORMAT adapterFormat, D3DFORMAT backBufferFormat )
{
    // Always request MIXED or SOFTWARE vertex processing do deal with fall backs
    if ((dwBehavior & D3DCREATE_PUREDEVICE) || (dwBehavior & D3DCREATE_HARDWARE_VERTEXPROCESSING))
        return E_FAIL;

    // If using mixed, make sure the hardware can do vertex blending
    if( ( dwBehavior & D3DCREATE_MIXED_VERTEXPROCESSING ) &&
        pCaps->MaxVertexBlendMatrices < 2 )
    {
        return E_FAIL;
    }

    return S_OK;
}




//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: Restore device-memory objects and state after a device is created or
//       resized.
//-----------------------------------------------------------------------------
HRESULT RestoreDeviceObjects()
{
    HRESULT hr;

    // Setup render state
    Device->SetRenderState( D3DRS_LIGHTING,         TRUE );
    Device->SetRenderState( D3DRS_DITHERENABLE,     TRUE );
    Device->SetRenderState( D3DRS_ZENABLE,          TRUE );
    Device->SetRenderState( D3DRS_CULLMODE,         D3DCULL_CCW );
    Device->SetRenderState( D3DRS_AMBIENT,          0x33333333 );
    Device->SetRenderState( D3DRS_NORMALIZENORMALS, TRUE );
    Device->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
    Device->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );

    // Setup the arcball parameters
    m_ArcBall->SetWindow( m_d3dsdBackBuffer.Width, m_d3dsdBackBuffer.Height, 0.85f );
    m_ArcBall->SetRadius( m_fObjectRadius );

    // Restore Effect
    if ( m_pEffect )
        m_pEffect->OnResetDevice();

    // load the indexed vertex shaders
    for (DWORD iInfl = 0; iInfl < 4; ++iInfl)
    {
        LPD3DXBUFFER pCode;

        // Assemble the vertex shader file
        if( FAILED( hr = D3DXAssembleShaderFromResource(NULL, MAKEINTRESOURCE(IDD_SHADER1 + iInfl), NULL, NULL, 0, &pCode, NULL ) ) )
            return hr;

        // Create the vertex shader
        if( FAILED( hr = Device->CreateVertexShader( (DWORD*)pCode->GetBufferPointer(),
                                                           &m_pIndexedVertexShader[iInfl] ) ) )
        {
            return hr;
        }

        pCode->Release();
    }

    return S_OK;
}


//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects()
// Desc: Called when the device-dependent objects are about to be lost.
//-----------------------------------------------------------------------------
HRESULT InvalidateDeviceObjects()
{
    // release the vertex shaders
    for (DWORD iInfl = 0; iInfl < 4; ++iInfl)
    {
        SAFE_RELEASE(m_pIndexedVertexShader[iInfl]);
    }

    // Invalidate Effect
    if ( m_pEffect )
        m_pEffect->OnLostDevice();

    return S_OK;
}

//-----------------------------------------------------------------------------
// Name: DeleteDeviceObjects()
// Desc: Called when the app is exiting, or the device is being changed,
//       this function deletes any device dependent objects.
//-----------------------------------------------------------------------------
HRESULT DeleteDeviceObjects()
{
    CAllocateHierarchy Alloc;

    D3DXFrameDestroy(m_pFrameRoot, &Alloc);

    SAFE_RELEASE(m_pAnimController);

    SAFE_RELEASE(m_pEffect);

    return S_OK;
}

//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: This creates all device-dependent managed objects, such as managed
//       textures and managed vertex buffers.
//-----------------------------------------------------------------------------
HRESULT InitDeviceObjects()
{
    HRESULT    hr;
    CAllocateHierarchy Alloc;

    Device->GetDeviceCaps(&m_d3dCaps); 

    LPDIRECT3DSURFACE9 pBackBuffer = NULL;
    Device->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer );
    pBackBuffer->GetDesc( &m_d3dsdBackBuffer );
    pBackBuffer->Release();

    hr = D3DXLoadMeshHierarchyFromX(TEXT("JianSheng.X"), D3DXMESH_MANAGED, Device, &Alloc, NULL, &m_pFrameRoot, &m_pAnimController);
    if (FAILED(hr))
        return hr;

    hr = SetupBoneMatrixPointers(m_pFrameRoot);
    if (FAILED(hr))
        return hr;

    hr = D3DXFrameCalculateBoundingSphere(m_pFrameRoot, &m_vObjectCenter, &m_fObjectRadius);
    if (FAILED(hr))
        return hr;

    // Create Effect for HLSL skinning
    // Find the vertex shader file
    hr = D3DXCreateEffectFromFile( Device, _T("SkinnedMesh.fx"), NULL,
                                       NULL, D3DXSHADER_DEBUG, NULL, &m_pEffect, NULL);
    if (FAILED(hr))
        return hr;


    return S_OK;
}

//-----------------------------------------------------------------------------
// Name: D3DXQuaternionUnitAxisToUnitAxis2
// Desc: Axis to axis quaternion double angle (no normalization)
//       Takes two points on unit sphere an angle THETA apart, returns
//       quaternion that represents a rotation around cross product by 2*THETA.
//-----------------------------------------------------------------------------
inline D3DXQUATERNION* WINAPI D3DXQuaternionUnitAxisToUnitAxis2
( D3DXQUATERNION *pOut, const D3DXVECTOR3 *pvFrom, const D3DXVECTOR3 *pvTo)
{
    D3DXVECTOR3 vAxis;
    D3DXVec3Cross(&vAxis, pvFrom, pvTo);    // proportional to sin(theta)
    pOut->x = vAxis.x;
    pOut->y = vAxis.y;
    pOut->z = vAxis.z;
    pOut->w = D3DXVec3Dot( pvFrom, pvTo );
    return pOut;
}


//-----------------------------------------------------------------------------
// Name: D3DXQuaternionAxisToAxis
// Desc: Axis to axis quaternion 
//       Takes two points on unit sphere an angle THETA apart, returns
//       quaternion that represents a rotation around cross product by theta.
//-----------------------------------------------------------------------------
inline D3DXQUATERNION* WINAPI D3DXQuaternionAxisToAxis
( D3DXQUATERNION *pOut, const D3DXVECTOR3 *pvFrom, const D3DXVECTOR3 *pvTo)
{
    D3DXVECTOR3 vA, vB;
    D3DXVec3Normalize(&vA, pvFrom);
    D3DXVec3Normalize(&vB, pvTo);
    D3DXVECTOR3 vHalf(vA + vB);
    D3DXVec3Normalize(&vHalf, &vHalf);
    return D3DXQuaternionUnitAxisToUnitAxis2(pOut, &vA, &vHalf);
}



⌨️ 快捷键说明

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