📄 skinnedmesh.h
字号:
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 + -