📄 sdkmesh.cpp
字号:
bool bCopyStatic,
SDKMESH_CALLBACKS10* pLoaderCallbacks10, SDKMESH_CALLBACKS9* pLoaderCallbacks9 )
{
HRESULT hr = E_FAIL;
m_pDev9 = pDev9;
m_pDev10 = pDev10;
// Set outstanding resources to zero
m_NumOutstandingResources = 0;
if( bCopyStatic )
{
SDKMESH_HEADER* pHeader = (SDKMESH_HEADER*)pData;
SIZE_T StaticSize = (SIZE_T)(pHeader->HeaderSize + pHeader->NonBufferDataSize);
m_pHeapData = new BYTE[ StaticSize ];
if( !m_pHeapData )
return hr;
m_pStaticMeshData = m_pHeapData;
CopyMemory( m_pStaticMeshData, pData, StaticSize );
}
else
{
m_pHeapData = pData;
m_pStaticMeshData = pData;
}
// Pointer fixup
m_pMeshHeader = (SDKMESH_HEADER*)m_pStaticMeshData;
m_pVertexBufferArray = (SDKMESH_VERTEX_BUFFER_HEADER*)(m_pStaticMeshData + m_pMeshHeader->VertexStreamHeadersOffset);
m_pIndexBufferArray = (SDKMESH_INDEX_BUFFER_HEADER*)(m_pStaticMeshData + m_pMeshHeader->IndexStreamHeadersOffset);
m_pMeshArray = (SDKMESH_MESH*)(m_pStaticMeshData + m_pMeshHeader->MeshDataOffset);
m_pSubsetArray = (SDKMESH_SUBSET*)(m_pStaticMeshData + m_pMeshHeader->SubsetDataOffset);
m_pFrameArray = (SDKMESH_FRAME*)(m_pStaticMeshData + m_pMeshHeader->FrameDataOffset);
m_pMaterialArray = (SDKMESH_MATERIAL*)(m_pStaticMeshData + m_pMeshHeader->MaterialDataOffset);
// Setup subsets
for( UINT i=0; i<m_pMeshHeader->NumMeshes; i++ )
{
m_pMeshArray[i].pSubsets = (UINT*)(m_pStaticMeshData + m_pMeshArray[i].SubsetOffset);
m_pMeshArray[i].pFrameInfluences = (UINT*)(m_pStaticMeshData + m_pMeshArray[i].FrameInfluenceOffset);
}
// error condition
if( m_pMeshHeader->Version != SDKMESH_FILE_VERSION )
{
hr = E_NOINTERFACE;
goto Error;
}
// Setup buffer data pointer
BYTE* pBufferData = pData + m_pMeshHeader->HeaderSize + m_pMeshHeader->NonBufferDataSize;
// Get the start of the buffer data
UINT64 BufferDataStart = m_pMeshHeader->HeaderSize + m_pMeshHeader->NonBufferDataSize;
// Create Adjacency Indices
if( pDev10 && bCreateAdjacencyIndices )
CreateAdjacencyIndices( pDev10, 0.001f, pBufferData - BufferDataStart );
// Create VBs
for( UINT i=0; i<m_pMeshHeader->NumVertexBuffers; i++ )
{
BYTE* pVertices = NULL;
pVertices = (BYTE*)( pBufferData + ( m_pVertexBufferArray[i].DataOffset - BufferDataStart ) );
if( pDev10 )
CreateVertexBuffer( pDev10, &m_pVertexBufferArray[i], pVertices, pLoaderCallbacks10 );
else if( pDev9 )
CreateVertexBuffer( pDev9, &m_pVertexBufferArray[i], pVertices, pLoaderCallbacks9 );
}
// Create IBs
for( UINT i=0; i<m_pMeshHeader->NumIndexBuffers; i++ )
{
BYTE* pIndices = NULL;
pIndices = (BYTE*)( pBufferData + ( m_pIndexBufferArray[i].DataOffset - BufferDataStart ) );
if( pDev10 )
CreateIndexBuffer( pDev10, &m_pIndexBufferArray[i], pIndices, pLoaderCallbacks10 );
else if( pDev9 )
CreateIndexBuffer( pDev9, &m_pIndexBufferArray[i], pIndices, pLoaderCallbacks9 );
}
// Load Materials
if( pDev10 )
LoadMaterials( pDev10, m_pMaterialArray, m_pMeshHeader->NumMaterials, pLoaderCallbacks10 );
else if( pDev9 )
LoadMaterials( pDev9, m_pMaterialArray, m_pMeshHeader->NumMaterials, pLoaderCallbacks9 );
// Create a place to store our bind pose frame matrices
m_pBindPoseFrameMatrices = new D3DXMATRIX[ m_pMeshHeader->NumFrames ];
if( !m_pBindPoseFrameMatrices )
goto Error;
// Create a place to store our transformed frame matrices
m_pTransformedFrameMatrices = new D3DXMATRIX[ m_pMeshHeader->NumFrames ];
if( !m_pTransformedFrameMatrices )
goto Error;
hr = S_OK;
Error:
if( !pLoaderCallbacks10 && !pLoaderCallbacks9 )
{
CheckLoadDone();
}
return hr;
}
//--------------------------------------------------------------------------------------
// transform bind pose frame using a recursive traversal
//--------------------------------------------------------------------------------------
void CDXUTSDKMesh::TransformBindPoseFrame( UINT iFrame, D3DXMATRIX* pParentWorld )
{
if( !m_pBindPoseFrameMatrices )
return;
// Transform ourselves
D3DXMATRIX LocalWorld;
D3DXMatrixMultiply( &LocalWorld, &m_pFrameArray[iFrame].Matrix, pParentWorld );
m_pBindPoseFrameMatrices[iFrame] = LocalWorld;
// Transform our siblings
if( m_pFrameArray[iFrame].SiblingFrame != INVALID_FRAME )
TransformBindPoseFrame( m_pFrameArray[iFrame].SiblingFrame, pParentWorld);
// Transform our children
if( m_pFrameArray[iFrame].ChildFrame != INVALID_FRAME )
TransformBindPoseFrame( m_pFrameArray[iFrame].ChildFrame, &LocalWorld );
}
//--------------------------------------------------------------------------------------
// transform frame using a recursive traversal
//--------------------------------------------------------------------------------------
void CDXUTSDKMesh::TransformFrame( UINT iFrame, D3DXMATRIX* pParentWorld, double fTime )
{
// Get the tick data
D3DXMATRIX LocalTransform;
UINT iTick = GetAnimationKeyFromTime( fTime );
if( INVALID_ANIMATION_DATA != m_pFrameArray[iFrame].AnimationDataIndex )
{
SDKANIMATION_FRAME_DATA* pFrameData = &m_pAnimationFrameData[ m_pFrameArray[iFrame].AnimationDataIndex ];
SDKANIMATION_DATA* pData = &pFrameData->pAnimationData[ iTick ];
// turn it into a matrix (Ignore scaling for now)
D3DXVECTOR3 parentPos = pData->Translation;
D3DXMATRIX mTranslate;
D3DXMatrixTranslation( &mTranslate, parentPos.x, parentPos.y, parentPos.z );
D3DXQUATERNION quat;
D3DXMATRIX mQuat;
quat.w = pData->Orientation.w;
quat.x = pData->Orientation.x;
quat.y = pData->Orientation.y;
quat.z = pData->Orientation.z;
if( quat.w == 0 && quat.x == 0 && quat.y == 0 && quat.z == 0 )
D3DXQuaternionIdentity( &quat );
D3DXQuaternionNormalize( &quat, &quat );
D3DXMatrixRotationQuaternion( &mQuat, &quat );
LocalTransform = ( mQuat * mTranslate );
}
else
{
LocalTransform = m_pFrameArray[iFrame].Matrix;
}
// Transform ourselves
D3DXMATRIX LocalWorld;
D3DXMatrixMultiply( &LocalWorld, &LocalTransform, pParentWorld );
m_pTransformedFrameMatrices[iFrame] = LocalWorld;
// Transform our siblings
if( m_pFrameArray[iFrame].SiblingFrame != INVALID_FRAME )
TransformFrame( m_pFrameArray[iFrame].SiblingFrame, pParentWorld, fTime );
// Transform our children
if( m_pFrameArray[iFrame].ChildFrame != INVALID_FRAME )
TransformFrame( m_pFrameArray[iFrame].ChildFrame, &LocalWorld, fTime );
}
//--------------------------------------------------------------------------------------
// transform frame assuming that it is an absolute transformation
//--------------------------------------------------------------------------------------
void CDXUTSDKMesh::TransformFrameAbsolute( UINT iFrame, double fTime )
{
D3DXMATRIX mTrans1;
D3DXMATRIX mTrans2;
D3DXMATRIX mRot1;
D3DXMATRIX mRot2;
D3DXQUATERNION quat1;
D3DXQUATERNION quat2;
D3DXMATRIX mTo;
D3DXMATRIX mInvTo;
D3DXMATRIX mFrom;
UINT iTick = GetAnimationKeyFromTime( fTime );
if( INVALID_ANIMATION_DATA != m_pFrameArray[iFrame].AnimationDataIndex )
{
SDKANIMATION_FRAME_DATA* pFrameData = &m_pAnimationFrameData[ m_pFrameArray[iFrame].AnimationDataIndex ];
SDKANIMATION_DATA* pData = &pFrameData->pAnimationData[ iTick ];
SDKANIMATION_DATA* pDataOrig = &pFrameData->pAnimationData[ 0 ];
D3DXMatrixTranslation( &mTrans1, -pDataOrig->Translation.x,
-pDataOrig->Translation.y,
-pDataOrig->Translation.z );
D3DXMatrixTranslation( &mTrans2, pData->Translation.x,
pData->Translation.y,
pData->Translation.z );
quat1.x = pDataOrig->Orientation.x;
quat1.y = pDataOrig->Orientation.y;
quat1.z = pDataOrig->Orientation.z;
quat1.w = pDataOrig->Orientation.w;
D3DXQuaternionInverse( &quat1, &quat1 );
D3DXMatrixRotationQuaternion( &mRot1, &quat1 );
mInvTo = mTrans1 * mRot1;
quat2.x = pData->Orientation.x;
quat2.y = pData->Orientation.y;
quat2.z = pData->Orientation.z;
quat2.w = pData->Orientation.w;
D3DXMatrixRotationQuaternion( &mRot2, &quat2 );
mFrom = mRot2 * mTrans2;
D3DXMATRIX mOutput = mInvTo * mFrom;
m_pTransformedFrameMatrices[iFrame] = mOutput;
}
}
//--------------------------------------------------------------------------------------
#define MAX_D3D10_VERTEX_STREAMS D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT
void CDXUTSDKMesh::RenderMesh( UINT iMesh,
bool bAdjacent,
ID3D10Device* pd3dDevice,
ID3D10EffectTechnique* pTechnique,
ID3D10EffectShaderResourceVariable* ptxDiffuse,
ID3D10EffectShaderResourceVariable* ptxNormal,
ID3D10EffectShaderResourceVariable* ptxSpecular,
ID3D10EffectVectorVariable* pvDiffuse,
ID3D10EffectVectorVariable* pvSpecular )
{
if( 0 < GetOutstandingBufferResources() )
return;
SDKMESH_MESH* pMesh = &m_pMeshArray[iMesh];
UINT Strides[MAX_D3D10_VERTEX_STREAMS];
UINT Offsets[MAX_D3D10_VERTEX_STREAMS];
ID3D10Buffer* pVB[MAX_D3D10_VERTEX_STREAMS];
if( pMesh->NumVertexBuffers > MAX_D3D10_VERTEX_STREAMS )
return;
for( UINT64 i=0; i<pMesh->NumVertexBuffers; i++ )
{
pVB[i] = m_pVertexBufferArray[ pMesh->VertexBuffers[i] ].pVB10;
Strides[i] = (UINT)m_pVertexBufferArray[ pMesh->VertexBuffers[i] ].StrideBytes;
Offsets[i] = 0;
}
SDKMESH_INDEX_BUFFER_HEADER* pIndexBufferArray;
if( bAdjacent )
pIndexBufferArray = m_pAdjacencyIndexBufferArray;
else
pIndexBufferArray = m_pIndexBufferArray;
ID3D10Buffer* pIB = pIndexBufferArray[ pMesh->IndexBuffer ].pIB10;
DXGI_FORMAT ibFormat = DXGI_FORMAT_R16_UINT;
switch( pIndexBufferArray[ pMesh->IndexBuffer ].IndexType )
{
case IT_16BIT:
ibFormat = DXGI_FORMAT_R16_UINT;
break;
case IT_32BIT:
ibFormat = DXGI_FORMAT_R32_UINT;
break;
};
pd3dDevice->IASetVertexBuffers( 0, pMesh->NumVertexBuffers, pVB, Strides, Offsets );
pd3dDevice->IASetIndexBuffer( pIB, ibFormat, 0 );
D3D10_TECHNIQUE_DESC techDesc;
pTechnique->GetDesc( &techDesc );
SDKMESH_SUBSET* pSubset = NULL;
SDKMESH_MATERIAL* pMat = NULL;
D3D10_PRIMITIVE_TOPOLOGY PrimType;
for( UINT p = 0; p < techDesc.Passes; ++p )
{
for( UINT subset = 0; subset < pMesh->NumSubsets; subset++ )
{
pSubset = &m_pSubsetArray[ pMesh->pSubsets[subset] ];
PrimType = GetPrimitiveType10( (SDKMESH_PRIMITIVE_TYPE)pSubset->PrimitiveType );
if( bAdjacent )
{
switch( PrimType )
{
case D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST:
PrimType = D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ;
break;
case D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP:
PrimType = D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ;
break;
case D3D10_PRIMITIVE_TOPOLOGY_LINELIST:
PrimType = D3D10_PRIMITIVE_TOPOLOGY_LINELIST_ADJ;
break;
case D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP:
PrimType = D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ;
break;
}
}
pd3dDevice->IASetPrimitiveTopology( PrimType );
pMat = &m_pMaterialArray[ pSubset->MaterialID ];
if( ptxDiffuse && !IsErrorResource(pMat->pDiffuseRV10) )
ptxDiffuse->SetResource( pMat->pDiffuseRV10 );
if( ptxNormal && !IsErrorResource(pMat->pNormalRV10) )
ptxNormal->SetResource( pMat->pNormalRV10 );
if( ptxSpecular && !IsErrorResource(pMat->pSpecularRV10) )
ptxSpecular->SetResource( pMat->pSpecularRV10 );
if( pvDiffuse )
pvDiffuse->SetFloatVector( pMat->Diffuse );
if( pvSpecular )
pvSpecular->SetFloatVector( pMat->Specular );
pTechnique->GetPassByIndex( p )->Apply(0);
UINT IndexCount = (UINT)pSubset->IndexCount;
UINT IndexStart = (UINT)pSubset->IndexStart;
UINT VertexStart = (UINT)pSubset->VertexStart;
if( bAdjacent )
{
IndexCount *= 2;
IndexStart *= 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -