1 //--------------------------------------------------------------------------------------
\r
4 // The SDK Mesh format (.sdkmesh) is not a recommended file format for games.
\r
5 // It was designed to meet the specific needs of the SDK samples. Any real-world
\r
6 // applications should avoid this file format in favor of a destination format that
\r
7 // meets the specific needs of the application.
\r
9 // Copyright (c) Microsoft Corporation. All rights reserved.
\r
10 //--------------------------------------------------------------------------------------
\r
12 #include "SDKMesh.h"
\r
13 #include "SDKMisc.h"
\r
15 //--------------------------------------------------------------------------------------
\r
16 void CDXUTSDKMesh::LoadMaterials( ID3D11Device* pd3dDevice, SDKMESH_MATERIAL* pMaterials, UINT numMaterials,
\r
17 SDKMESH_CALLBACKS11* pLoaderCallbacks )
\r
20 char strPath[MAX_PATH];
\r
22 if( pLoaderCallbacks && pLoaderCallbacks->pCreateTextureFromFile )
\r
24 for( UINT m = 0; m < numMaterials; m++ )
\r
26 pMaterials[m].pDiffuseTexture11 = NULL;
\r
27 pMaterials[m].pNormalTexture11 = NULL;
\r
28 pMaterials[m].pSpecularTexture11 = NULL;
\r
29 pMaterials[m].pDiffuseRV11 = NULL;
\r
30 pMaterials[m].pNormalRV11 = NULL;
\r
31 pMaterials[m].pSpecularRV11 = NULL;
\r
34 if( pMaterials[m].DiffuseTexture[0] != 0 )
\r
36 pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice,
\r
37 pMaterials[m].DiffuseTexture, &pMaterials[m].pDiffuseRV11,
\r
38 pLoaderCallbacks->pContext );
\r
40 if( pMaterials[m].NormalTexture[0] != 0 )
\r
42 pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice,
\r
43 pMaterials[m].NormalTexture, &pMaterials[m].pNormalRV11,
\r
44 pLoaderCallbacks->pContext );
\r
46 if( pMaterials[m].SpecularTexture[0] != 0 )
\r
48 pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice,
\r
49 pMaterials[m].SpecularTexture, &pMaterials[m].pSpecularRV11,
\r
50 pLoaderCallbacks->pContext );
\r
56 for( UINT m = 0; m < numMaterials; m++ )
\r
58 pMaterials[m].pDiffuseTexture11 = NULL;
\r
59 pMaterials[m].pNormalTexture11 = NULL;
\r
60 pMaterials[m].pSpecularTexture11 = NULL;
\r
61 pMaterials[m].pDiffuseRV11 = NULL;
\r
62 pMaterials[m].pNormalRV11 = NULL;
\r
63 pMaterials[m].pSpecularRV11 = NULL;
\r
66 if( pMaterials[m].DiffuseTexture[0] != 0 )
\r
68 sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].DiffuseTexture );
\r
69 if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice, DXUTGetD3D11DeviceContext(),
\r
70 strPath, &pMaterials[m].pDiffuseRV11,
\r
72 pMaterials[m].pDiffuseRV11 = ( ID3D11ShaderResourceView* )ERROR_RESOURCE_VALUE;
\r
75 if( pMaterials[m].NormalTexture[0] != 0 )
\r
77 sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].NormalTexture );
\r
78 if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice, DXUTGetD3D11DeviceContext(),
\r
80 &pMaterials[m].pNormalRV11 ) ) )
\r
81 pMaterials[m].pNormalRV11 = ( ID3D11ShaderResourceView* )ERROR_RESOURCE_VALUE;
\r
83 if( pMaterials[m].SpecularTexture[0] != 0 )
\r
85 sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].SpecularTexture );
\r
86 if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice, DXUTGetD3D11DeviceContext(),
\r
88 &pMaterials[m].pSpecularRV11 ) ) )
\r
89 pMaterials[m].pSpecularRV11 = ( ID3D11ShaderResourceView* )ERROR_RESOURCE_VALUE;
\r
95 //--------------------------------------------------------------------------------------
\r
96 void CDXUTSDKMesh::LoadMaterials( IDirect3DDevice9* pd3dDevice, SDKMESH_MATERIAL* pMaterials, UINT numMaterials,
\r
97 SDKMESH_CALLBACKS9* pLoaderCallbacks )
\r
99 char strPath[MAX_PATH];
\r
101 if( pLoaderCallbacks && pLoaderCallbacks->pCreateTextureFromFile )
\r
103 for( UINT m = 0; m < numMaterials; m++ )
\r
105 pMaterials[m].pDiffuseTexture9 = NULL;
\r
106 pMaterials[m].pNormalTexture9 = NULL;
\r
107 pMaterials[m].pSpecularTexture9 = NULL;
\r
110 if( pMaterials[m].DiffuseTexture[0] != 0 )
\r
112 pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice,
\r
113 pMaterials[m].DiffuseTexture,
\r
114 &pMaterials[m].pDiffuseTexture9,
\r
115 pLoaderCallbacks->pContext );
\r
117 if( pMaterials[m].NormalTexture[0] != 0 )
\r
119 pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice,
\r
120 pMaterials[m].NormalTexture, &pMaterials[m].pNormalTexture9,
\r
121 pLoaderCallbacks->pContext );
\r
123 if( pMaterials[m].SpecularTexture[0] != 0 )
\r
125 pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice,
\r
126 pMaterials[m].SpecularTexture,
\r
127 &pMaterials[m].pSpecularTexture9,
\r
128 pLoaderCallbacks->pContext );
\r
134 for( UINT m = 0; m < numMaterials; m++ )
\r
136 pMaterials[m].pDiffuseTexture9 = NULL;
\r
137 pMaterials[m].pNormalTexture9 = NULL;
\r
138 pMaterials[m].pSpecularTexture9 = NULL;
\r
139 pMaterials[m].pDiffuseRV11 = NULL;
\r
140 pMaterials[m].pNormalRV11 = NULL;
\r
141 pMaterials[m].pSpecularRV11 = NULL;
\r
144 if( pMaterials[m].DiffuseTexture[0] != 0 )
\r
146 sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].DiffuseTexture );
\r
147 if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice,
\r
149 &pMaterials[m].pDiffuseTexture9 ) ) )
\r
150 pMaterials[m].pDiffuseTexture9 = ( IDirect3DTexture9* )ERROR_RESOURCE_VALUE;
\r
152 if( pMaterials[m].NormalTexture[0] != 0 )
\r
154 sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].NormalTexture );
\r
155 if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice,
\r
157 &pMaterials[m].pNormalTexture9 ) ) )
\r
158 pMaterials[m].pNormalTexture9 = ( IDirect3DTexture9* )ERROR_RESOURCE_VALUE;
\r
160 if( pMaterials[m].SpecularTexture[0] != 0 )
\r
162 sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].SpecularTexture );
\r
163 if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice,
\r
165 &pMaterials[m].pSpecularTexture9 ) ) )
\r
166 pMaterials[m].pSpecularTexture9 = ( IDirect3DTexture9* )ERROR_RESOURCE_VALUE;
\r
173 //--------------------------------------------------------------------------------------
\r
174 HRESULT CDXUTSDKMesh::CreateVertexBuffer( ID3D11Device* pd3dDevice, SDKMESH_VERTEX_BUFFER_HEADER* pHeader,
\r
175 void* pVertices, SDKMESH_CALLBACKS11* pLoaderCallbacks )
\r
178 pHeader->DataOffset = 0;
\r
180 D3D11_BUFFER_DESC bufferDesc;
\r
181 bufferDesc.ByteWidth = ( UINT )( pHeader->SizeBytes );
\r
182 bufferDesc.Usage = D3D11_USAGE_DEFAULT;
\r
183 bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
\r
184 bufferDesc.CPUAccessFlags = 0;
\r
185 bufferDesc.MiscFlags = 0;
\r
187 if( pLoaderCallbacks && pLoaderCallbacks->pCreateVertexBuffer )
\r
189 pLoaderCallbacks->pCreateVertexBuffer( pd3dDevice, &pHeader->pVB11, bufferDesc, pVertices,
\r
190 pLoaderCallbacks->pContext );
\r
194 D3D11_SUBRESOURCE_DATA InitData;
\r
195 InitData.pSysMem = pVertices;
\r
196 hr = pd3dDevice->CreateBuffer( &bufferDesc, &InitData, &pHeader->pVB11 );
\r
203 //--------------------------------------------------------------------------------------
\r
204 HRESULT CDXUTSDKMesh::CreateIndexBuffer( ID3D11Device* pd3dDevice, SDKMESH_INDEX_BUFFER_HEADER* pHeader,
\r
205 void* pIndices, SDKMESH_CALLBACKS11* pLoaderCallbacks )
\r
208 pHeader->DataOffset = 0;
\r
210 D3D11_BUFFER_DESC bufferDesc;
\r
211 bufferDesc.ByteWidth = ( UINT )( pHeader->SizeBytes );
\r
212 bufferDesc.Usage = D3D11_USAGE_DEFAULT;
\r
213 bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
\r
214 bufferDesc.CPUAccessFlags = 0;
\r
215 bufferDesc.MiscFlags = 0;
\r
217 if( pLoaderCallbacks && pLoaderCallbacks->pCreateIndexBuffer )
\r
219 pLoaderCallbacks->pCreateIndexBuffer( pd3dDevice, &pHeader->pIB11, bufferDesc, pIndices,
\r
220 pLoaderCallbacks->pContext );
\r
224 D3D11_SUBRESOURCE_DATA InitData;
\r
225 InitData.pSysMem = pIndices;
\r
226 hr = pd3dDevice->CreateBuffer( &bufferDesc, &InitData, &pHeader->pIB11 );
\r
233 //--------------------------------------------------------------------------------------
\r
234 HRESULT CDXUTSDKMesh::CreateVertexBuffer( IDirect3DDevice9* pd3dDevice, SDKMESH_VERTEX_BUFFER_HEADER* pHeader,
\r
235 void* pVertices, SDKMESH_CALLBACKS9* pLoaderCallbacks )
\r
239 pHeader->DataOffset = 0;
\r
240 if( pLoaderCallbacks && pLoaderCallbacks->pCreateVertexBuffer )
\r
242 pLoaderCallbacks->pCreateVertexBuffer( pd3dDevice, &pHeader->pVB9, ( UINT )pHeader->SizeBytes,
\r
243 D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, pVertices,
\r
244 pLoaderCallbacks->pContext );
\r
248 hr = pd3dDevice->CreateVertexBuffer( ( UINT )pHeader->SizeBytes,
\r
249 D3DUSAGE_WRITEONLY,
\r
256 if( SUCCEEDED( hr ) )
\r
258 void* pLockedVerts = NULL;
\r
259 V_RETURN( pHeader->pVB9->Lock( 0, 0, &pLockedVerts, 0 ) );
\r
260 CopyMemory( pLockedVerts, pVertices, ( size_t )pHeader->SizeBytes );
\r
261 pHeader->pVB9->Unlock();
\r
268 //--------------------------------------------------------------------------------------
\r
269 HRESULT CDXUTSDKMesh::CreateIndexBuffer( IDirect3DDevice9* pd3dDevice, SDKMESH_INDEX_BUFFER_HEADER* pHeader,
\r
270 void* pIndices, SDKMESH_CALLBACKS9* pLoaderCallbacks )
\r
274 pHeader->DataOffset = 0;
\r
276 D3DFORMAT ibFormat = D3DFMT_INDEX16;
\r
277 switch( pHeader->IndexType )
\r
280 ibFormat = D3DFMT_INDEX16;
\r
283 ibFormat = D3DFMT_INDEX32;
\r
287 if( pLoaderCallbacks && pLoaderCallbacks->pCreateIndexBuffer )
\r
289 pLoaderCallbacks->pCreateIndexBuffer( pd3dDevice, &pHeader->pIB9, ( UINT )pHeader->SizeBytes,
\r
290 D3DUSAGE_WRITEONLY, ibFormat, D3DPOOL_DEFAULT, pIndices,
\r
291 pLoaderCallbacks->pContext );
\r
295 hr = pd3dDevice->CreateIndexBuffer( ( UINT )( pHeader->SizeBytes ),
\r
296 D3DUSAGE_WRITEONLY,
\r
302 if( SUCCEEDED( hr ) )
\r
304 void* pLockedIndices = NULL;
\r
305 V_RETURN( pHeader->pIB9->Lock( 0, 0, &pLockedIndices, 0 ) );
\r
306 CopyMemory( pLockedIndices, pIndices, ( size_t )( pHeader->SizeBytes ) );
\r
307 pHeader->pIB9->Unlock();
\r
314 //--------------------------------------------------------------------------------------
\r
315 HRESULT CDXUTSDKMesh::CreateFromFile( ID3D11Device* pDev11,
\r
316 IDirect3DDevice9* pDev9,
\r
317 LPCTSTR szFileName,
\r
318 bool bCreateAdjacencyIndices,
\r
319 SDKMESH_CALLBACKS11* pLoaderCallbacks11,
\r
320 SDKMESH_CALLBACKS9* pLoaderCallbacks9 )
\r
324 // Find the path for the file
\r
325 V_RETURN( DXUTFindDXSDKMediaFileCch( m_strPathW, sizeof( m_strPathW ) / sizeof( WCHAR ), szFileName ) );
\r
328 m_hFile = CreateFile( m_strPathW, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN,
\r
330 if( INVALID_HANDLE_VALUE == m_hFile )
\r
331 return DXUTERR_MEDIANOTFOUND;
\r
333 // Change the path to just the directory
\r
334 WCHAR* pLastBSlash = wcsrchr( m_strPathW, L'\\' );
\r
336 *( pLastBSlash + 1 ) = L'\0';
\r
338 *m_strPathW = L'\0';
\r
340 WideCharToMultiByte( CP_ACP, 0, m_strPathW, -1, m_strPath, MAX_PATH, NULL, FALSE );
\r
342 // Get the file size
\r
343 LARGE_INTEGER FileSize;
\r
344 GetFileSizeEx( m_hFile, &FileSize );
\r
345 UINT cBytes = FileSize.LowPart;
\r
348 m_pStaticMeshData = new BYTE[ cBytes ];
\r
349 if( !m_pStaticMeshData )
\r
351 CloseHandle( m_hFile );
\r
352 return E_OUTOFMEMORY;
\r
355 // Read in the file
\r
357 if( !ReadFile( m_hFile, m_pStaticMeshData, cBytes, &dwBytesRead, NULL ) )
\r
360 CloseHandle( m_hFile );
\r
362 if( SUCCEEDED( hr ) )
\r
364 hr = CreateFromMemory( pDev11,
\r
368 bCreateAdjacencyIndices,
\r
370 pLoaderCallbacks11,
\r
371 pLoaderCallbacks9 );
\r
373 delete []m_pStaticMeshData;
\r
379 HRESULT CDXUTSDKMesh::CreateFromMemory( ID3D11Device* pDev11,
\r
380 IDirect3DDevice9* pDev9,
\r
383 bool bCreateAdjacencyIndices,
\r
385 SDKMESH_CALLBACKS11* pLoaderCallbacks11,
\r
386 SDKMESH_CALLBACKS9* pLoaderCallbacks9 )
\r
388 HRESULT hr = E_FAIL;
\r
389 D3DXVECTOR3 lower;
\r
390 D3DXVECTOR3 upper;
\r
395 // Set outstanding resources to zero
\r
396 m_NumOutstandingResources = 0;
\r
400 SDKMESH_HEADER* pHeader = ( SDKMESH_HEADER* )pData;
\r
402 SIZE_T StaticSize = ( SIZE_T )( pHeader->HeaderSize + pHeader->NonBufferDataSize );
\r
403 m_pHeapData = new BYTE[ StaticSize ];
\r
407 m_pStaticMeshData = m_pHeapData;
\r
409 CopyMemory( m_pStaticMeshData, pData, StaticSize );
\r
413 m_pHeapData = pData;
\r
414 m_pStaticMeshData = pData;
\r
418 m_pMeshHeader = ( SDKMESH_HEADER* )m_pStaticMeshData;
\r
419 m_pVertexBufferArray = ( SDKMESH_VERTEX_BUFFER_HEADER* )( m_pStaticMeshData +
\r
420 m_pMeshHeader->VertexStreamHeadersOffset );
\r
421 m_pIndexBufferArray = ( SDKMESH_INDEX_BUFFER_HEADER* )( m_pStaticMeshData +
\r
422 m_pMeshHeader->IndexStreamHeadersOffset );
\r
423 m_pMeshArray = ( SDKMESH_MESH* )( m_pStaticMeshData + m_pMeshHeader->MeshDataOffset );
\r
424 m_pSubsetArray = ( SDKMESH_SUBSET* )( m_pStaticMeshData + m_pMeshHeader->SubsetDataOffset );
\r
425 m_pFrameArray = ( SDKMESH_FRAME* )( m_pStaticMeshData + m_pMeshHeader->FrameDataOffset );
\r
426 m_pMaterialArray = ( SDKMESH_MATERIAL* )( m_pStaticMeshData + m_pMeshHeader->MaterialDataOffset );
\r
429 for( UINT i = 0; i < m_pMeshHeader->NumMeshes; i++ )
\r
431 m_pMeshArray[i].pSubsets = ( UINT* )( m_pStaticMeshData + m_pMeshArray[i].SubsetOffset );
\r
432 m_pMeshArray[i].pFrameInfluences = ( UINT* )( m_pStaticMeshData + m_pMeshArray[i].FrameInfluenceOffset );
\r
436 if( m_pMeshHeader->Version != SDKMESH_FILE_VERSION )
\r
438 hr = E_NOINTERFACE;
\r
442 // Setup buffer data pointer
\r
443 BYTE* pBufferData = pData + m_pMeshHeader->HeaderSize + m_pMeshHeader->NonBufferDataSize;
\r
445 // Get the start of the buffer data
\r
446 UINT64 BufferDataStart = m_pMeshHeader->HeaderSize + m_pMeshHeader->NonBufferDataSize;
\r
449 m_ppVertices = new BYTE*[m_pMeshHeader->NumVertexBuffers];
\r
450 for( UINT i = 0; i < m_pMeshHeader->NumVertexBuffers; i++ )
\r
452 BYTE* pVertices = NULL;
\r
453 pVertices = ( BYTE* )( pBufferData + ( m_pVertexBufferArray[i].DataOffset - BufferDataStart ) );
\r
456 CreateVertexBuffer( pDev11, &m_pVertexBufferArray[i], pVertices, pLoaderCallbacks11 );
\r
458 CreateVertexBuffer( pDev9, &m_pVertexBufferArray[i], pVertices, pLoaderCallbacks9 );
\r
460 m_ppVertices[i] = pVertices;
\r
464 m_ppIndices = new BYTE*[m_pMeshHeader->NumIndexBuffers];
\r
465 for( UINT i = 0; i < m_pMeshHeader->NumIndexBuffers; i++ )
\r
467 BYTE* pIndices = NULL;
\r
468 pIndices = ( BYTE* )( pBufferData + ( m_pIndexBufferArray[i].DataOffset - BufferDataStart ) );
\r
471 CreateIndexBuffer( pDev11, &m_pIndexBufferArray[i], pIndices, pLoaderCallbacks11 );
\r
473 CreateIndexBuffer( pDev9, &m_pIndexBufferArray[i], pIndices, pLoaderCallbacks9 );
\r
475 m_ppIndices[i] = pIndices;
\r
480 LoadMaterials( pDev11, m_pMaterialArray, m_pMeshHeader->NumMaterials, pLoaderCallbacks11 );
\r
482 LoadMaterials( pDev9, m_pMaterialArray, m_pMeshHeader->NumMaterials, pLoaderCallbacks9 );
\r
484 // Create a place to store our bind pose frame matrices
\r
485 m_pBindPoseFrameMatrices = new D3DXMATRIX[ m_pMeshHeader->NumFrames ];
\r
486 if( !m_pBindPoseFrameMatrices )
\r
489 // Create a place to store our transformed frame matrices
\r
490 m_pTransformedFrameMatrices = new D3DXMATRIX[ m_pMeshHeader->NumFrames ];
\r
491 if( !m_pTransformedFrameMatrices )
\r
493 m_pWorldPoseFrameMatrices = new D3DXMATRIX[ m_pMeshHeader->NumFrames ];
\r
494 if( !m_pWorldPoseFrameMatrices )
\r
497 SDKMESH_SUBSET* pSubset = NULL;
\r
498 D3D11_PRIMITIVE_TOPOLOGY PrimType;
\r
500 // update bounding volume
\r
501 SDKMESH_MESH* currentMesh = &m_pMeshArray[0];
\r
503 for (UINT meshi=0; meshi < m_pMeshHeader->NumMeshes; ++meshi) {
\r
504 lower.x = FLT_MAX; lower.y = FLT_MAX; lower.z = FLT_MAX;
\r
505 upper.x = -FLT_MAX; upper.y = -FLT_MAX; upper.z = -FLT_MAX;
\r
506 currentMesh = GetMesh( meshi );
\r
508 if (m_pIndexBufferArray[currentMesh->IndexBuffer].IndexType == IT_16BIT ) {
\r
514 for( UINT subset = 0; subset < currentMesh->NumSubsets; subset++ )
\r
516 pSubset = GetSubset( meshi, subset ); //&m_pSubsetArray[ currentMesh->pSubsets[subset] ];
\r
518 PrimType = GetPrimitiveType11( ( SDKMESH_PRIMITIVE_TYPE )pSubset->PrimitiveType );
\r
519 assert( PrimType == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );// only triangle lists are handled.
\r
521 UINT IndexCount = ( UINT )pSubset->IndexCount;
\r
522 UINT IndexStart = ( UINT )pSubset->IndexStart;
\r
530 //BYTE* pIndices = NULL;
\r
532 UINT *ind = ( UINT * )m_ppIndices[currentMesh->IndexBuffer];
\r
533 FLOAT *verts = ( FLOAT* )m_ppVertices[currentMesh->VertexBuffers[0]];
\r
534 UINT stride = (UINT)m_pVertexBufferArray[currentMesh->VertexBuffers[0]].StrideBytes;
\r
535 assert (stride % 4 == 0);
\r
537 for (UINT vertind = IndexStart; vertind < IndexStart + IndexCount; ++vertind) { //TODO: test 16 bit and 32 bit
\r
538 UINT current_ind=0;
\r
539 if (indsize == 2) {
\r
540 UINT ind_div2 = vertind / 2;
\r
541 current_ind = ind[ind_div2];
\r
542 if (vertind %2 ==0) {
\r
543 current_ind = current_ind << 16;
\r
544 current_ind = current_ind >> 16;
\r
546 current_ind = current_ind >> 16;
\r
549 current_ind = ind[vertind];
\r
552 D3DXVECTOR3 *pt = (D3DXVECTOR3*)&(verts[stride * current_ind]);
\r
553 if (pt->x < lower.x) {
\r
556 if (pt->y < lower.y) {
\r
559 if (pt->z < lower.z) {
\r
562 if (pt->x > upper.x) {
\r
565 if (pt->y > upper.y) {
\r
568 if (pt->z > upper.z) {
\r
571 //BYTE** m_ppVertices;
\r
572 //BYTE** m_ppIndices;
\r
574 //pd3dDeviceContext->DrawIndexed( IndexCount, IndexStart, VertexStart );
\r
577 D3DXVECTOR3 half = upper - lower;
\r
580 currentMesh->BoundingBoxCenter = lower + half;
\r
581 currentMesh->BoundingBoxExtents = half;
\r
591 if( !pLoaderCallbacks9 )
\r
599 //--------------------------------------------------------------------------------------
\r
600 // transform bind pose frame using a recursive traversal
\r
601 //--------------------------------------------------------------------------------------
\r
602 void CDXUTSDKMesh::TransformBindPoseFrame( UINT iFrame, D3DXMATRIX* pParentWorld )
\r
604 if( !m_pBindPoseFrameMatrices )
\r
607 // Transform ourselves
\r
608 D3DXMATRIX LocalWorld;
\r
609 D3DXMatrixMultiply( &LocalWorld, &m_pFrameArray[iFrame].Matrix, pParentWorld );
\r
610 m_pBindPoseFrameMatrices[iFrame] = LocalWorld;
\r
612 // Transform our siblings
\r
613 if( m_pFrameArray[iFrame].SiblingFrame != INVALID_FRAME )
\r
614 TransformBindPoseFrame( m_pFrameArray[iFrame].SiblingFrame, pParentWorld );
\r
616 // Transform our children
\r
617 if( m_pFrameArray[iFrame].ChildFrame != INVALID_FRAME )
\r
618 TransformBindPoseFrame( m_pFrameArray[iFrame].ChildFrame, &LocalWorld );
\r
621 //--------------------------------------------------------------------------------------
\r
622 // transform frame using a recursive traversal
\r
623 //--------------------------------------------------------------------------------------
\r
624 void CDXUTSDKMesh::TransformFrame( UINT iFrame, D3DXMATRIX* pParentWorld, double fTime )
\r
626 // Get the tick data
\r
627 D3DXMATRIX LocalTransform;
\r
628 UINT iTick = GetAnimationKeyFromTime( fTime );
\r
630 if( INVALID_ANIMATION_DATA != m_pFrameArray[iFrame].AnimationDataIndex )
\r
632 SDKANIMATION_FRAME_DATA* pFrameData = &m_pAnimationFrameData[ m_pFrameArray[iFrame].AnimationDataIndex ];
\r
633 SDKANIMATION_DATA* pData = &pFrameData->pAnimationData[ iTick ];
\r
635 // turn it into a matrix (Ignore scaling for now)
\r
636 D3DXVECTOR3 parentPos = pData->Translation;
\r
637 D3DXMATRIX mTranslate;
\r
638 D3DXMatrixTranslation( &mTranslate, parentPos.x, parentPos.y, parentPos.z );
\r
640 D3DXQUATERNION quat;
\r
642 quat.w = pData->Orientation.w;
\r
643 quat.x = pData->Orientation.x;
\r
644 quat.y = pData->Orientation.y;
\r
645 quat.z = pData->Orientation.z;
\r
646 if( quat.w == 0 && quat.x == 0 && quat.y == 0 && quat.z == 0 )
\r
647 D3DXQuaternionIdentity( &quat );
\r
648 D3DXQuaternionNormalize( &quat, &quat );
\r
649 D3DXMatrixRotationQuaternion( &mQuat, &quat );
\r
650 LocalTransform = ( mQuat * mTranslate );
\r
654 LocalTransform = m_pFrameArray[iFrame].Matrix;
\r
657 // Transform ourselves
\r
658 D3DXMATRIX LocalWorld;
\r
659 D3DXMatrixMultiply( &LocalWorld, &LocalTransform, pParentWorld );
\r
660 m_pTransformedFrameMatrices[iFrame] = LocalWorld;
\r
661 m_pWorldPoseFrameMatrices[iFrame] = LocalWorld;
\r
663 // Transform our siblings
\r
664 if( m_pFrameArray[iFrame].SiblingFrame != INVALID_FRAME )
\r
665 TransformFrame( m_pFrameArray[iFrame].SiblingFrame, pParentWorld, fTime );
\r
667 // Transform our children
\r
668 if( m_pFrameArray[iFrame].ChildFrame != INVALID_FRAME )
\r
669 TransformFrame( m_pFrameArray[iFrame].ChildFrame, &LocalWorld, fTime );
\r
672 //--------------------------------------------------------------------------------------
\r
673 // transform frame assuming that it is an absolute transformation
\r
674 //--------------------------------------------------------------------------------------
\r
675 void CDXUTSDKMesh::TransformFrameAbsolute( UINT iFrame, double fTime )
\r
677 D3DXMATRIX mTrans1;
\r
678 D3DXMATRIX mTrans2;
\r
681 D3DXQUATERNION quat1;
\r
682 D3DXQUATERNION quat2;
\r
687 UINT iTick = GetAnimationKeyFromTime( fTime );
\r
689 if( INVALID_ANIMATION_DATA != m_pFrameArray[iFrame].AnimationDataIndex )
\r
691 SDKANIMATION_FRAME_DATA* pFrameData = &m_pAnimationFrameData[ m_pFrameArray[iFrame].AnimationDataIndex ];
\r
692 SDKANIMATION_DATA* pData = &pFrameData->pAnimationData[ iTick ];
\r
693 SDKANIMATION_DATA* pDataOrig = &pFrameData->pAnimationData[ 0 ];
\r
695 D3DXMatrixTranslation( &mTrans1, -pDataOrig->Translation.x,
\r
696 -pDataOrig->Translation.y,
\r
697 -pDataOrig->Translation.z );
\r
698 D3DXMatrixTranslation( &mTrans2, pData->Translation.x,
\r
699 pData->Translation.y,
\r
700 pData->Translation.z );
\r
702 quat1.x = pDataOrig->Orientation.x;
\r
703 quat1.y = pDataOrig->Orientation.y;
\r
704 quat1.z = pDataOrig->Orientation.z;
\r
705 quat1.w = pDataOrig->Orientation.w;
\r
706 D3DXQuaternionInverse( &quat1, &quat1 );
\r
707 D3DXMatrixRotationQuaternion( &mRot1, &quat1 );
\r
708 mInvTo = mTrans1 * mRot1;
\r
710 quat2.x = pData->Orientation.x;
\r
711 quat2.y = pData->Orientation.y;
\r
712 quat2.z = pData->Orientation.z;
\r
713 quat2.w = pData->Orientation.w;
\r
714 D3DXMatrixRotationQuaternion( &mRot2, &quat2 );
\r
715 mFrom = mRot2 * mTrans2;
\r
717 D3DXMATRIX mOutput = mInvTo * mFrom;
\r
718 m_pTransformedFrameMatrices[iFrame] = mOutput;
\r
722 #define MAX_D3D11_VERTEX_STREAMS D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT
\r
723 //--------------------------------------------------------------------------------------
\r
724 void CDXUTSDKMesh::RenderMesh( UINT iMesh,
\r
726 ID3D11DeviceContext* pd3dDeviceContext,
\r
729 UINT iSpecularSlot )
\r
731 if( 0 < GetOutstandingBufferResources() )
\r
734 SDKMESH_MESH* pMesh = &m_pMeshArray[iMesh];
\r
736 UINT Strides[MAX_D3D11_VERTEX_STREAMS];
\r
737 UINT Offsets[MAX_D3D11_VERTEX_STREAMS];
\r
738 ID3D11Buffer* pVB[MAX_D3D11_VERTEX_STREAMS];
\r
740 if( pMesh->NumVertexBuffers > MAX_D3D11_VERTEX_STREAMS )
\r
743 for( UINT64 i = 0; i < pMesh->NumVertexBuffers; i++ )
\r
745 pVB[i] = m_pVertexBufferArray[ pMesh->VertexBuffers[i] ].pVB11;
\r
746 Strides[i] = ( UINT )m_pVertexBufferArray[ pMesh->VertexBuffers[i] ].StrideBytes;
\r
750 SDKMESH_INDEX_BUFFER_HEADER* pIndexBufferArray;
\r
752 pIndexBufferArray = m_pAdjacencyIndexBufferArray;
\r
754 pIndexBufferArray = m_pIndexBufferArray;
\r
756 ID3D11Buffer* pIB = pIndexBufferArray[ pMesh->IndexBuffer ].pIB11;
\r
757 DXGI_FORMAT ibFormat = DXGI_FORMAT_R16_UINT;
\r
758 switch( pIndexBufferArray[ pMesh->IndexBuffer ].IndexType )
\r
761 ibFormat = DXGI_FORMAT_R16_UINT;
\r
764 ibFormat = DXGI_FORMAT_R32_UINT;
\r
768 pd3dDeviceContext->IASetVertexBuffers( 0, pMesh->NumVertexBuffers, pVB, Strides, Offsets );
\r
769 pd3dDeviceContext->IASetIndexBuffer( pIB, ibFormat, 0 );
\r
771 SDKMESH_SUBSET* pSubset = NULL;
\r
772 SDKMESH_MATERIAL* pMat = NULL;
\r
773 D3D11_PRIMITIVE_TOPOLOGY PrimType;
\r
775 for( UINT subset = 0; subset < pMesh->NumSubsets; subset++ )
\r
777 pSubset = &m_pSubsetArray[ pMesh->pSubsets[subset] ];
\r
779 PrimType = GetPrimitiveType11( ( SDKMESH_PRIMITIVE_TYPE )pSubset->PrimitiveType );
\r
784 case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST:
\r
785 PrimType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ;
\r
787 case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP:
\r
788 PrimType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ;
\r
790 case D3D11_PRIMITIVE_TOPOLOGY_LINELIST:
\r
791 PrimType = D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ;
\r
793 case D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP:
\r
794 PrimType = D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ;
\r
799 pd3dDeviceContext->IASetPrimitiveTopology( PrimType );
\r
801 pMat = &m_pMaterialArray[ pSubset->MaterialID ];
\r
802 if( iDiffuseSlot != INVALID_SAMPLER_SLOT && !IsErrorResource( pMat->pDiffuseRV11 ) )
\r
803 pd3dDeviceContext->PSSetShaderResources( iDiffuseSlot, 1, &pMat->pDiffuseRV11 );
\r
804 if( iNormalSlot != INVALID_SAMPLER_SLOT && !IsErrorResource( pMat->pNormalRV11 ) )
\r
805 pd3dDeviceContext->PSSetShaderResources( iNormalSlot, 1, &pMat->pNormalRV11 );
\r
806 if( iSpecularSlot != INVALID_SAMPLER_SLOT && !IsErrorResource( pMat->pSpecularRV11 ) )
\r
807 pd3dDeviceContext->PSSetShaderResources( iSpecularSlot, 1, &pMat->pSpecularRV11 );
\r
809 UINT IndexCount = ( UINT )pSubset->IndexCount;
\r
810 UINT IndexStart = ( UINT )pSubset->IndexStart;
\r
811 UINT VertexStart = ( UINT )pSubset->VertexStart;
\r
818 pd3dDeviceContext->DrawIndexed( IndexCount, IndexStart, VertexStart );
\r
822 //--------------------------------------------------------------------------------------
\r
823 void CDXUTSDKMesh::RenderFrame( UINT iFrame,
\r
825 ID3D11DeviceContext* pd3dDeviceContext,
\r
828 UINT iSpecularSlot )
\r
830 if( !m_pStaticMeshData || !m_pFrameArray )
\r
833 if( m_pFrameArray[iFrame].Mesh != INVALID_MESH )
\r
835 RenderMesh( m_pFrameArray[iFrame].Mesh,
\r
843 // Render our children
\r
844 if( m_pFrameArray[iFrame].ChildFrame != INVALID_FRAME )
\r
845 RenderFrame( m_pFrameArray[iFrame].ChildFrame, bAdjacent, pd3dDeviceContext, iDiffuseSlot,
\r
846 iNormalSlot, iSpecularSlot );
\r
848 // Render our siblings
\r
849 if( m_pFrameArray[iFrame].SiblingFrame != INVALID_FRAME )
\r
850 RenderFrame( m_pFrameArray[iFrame].SiblingFrame, bAdjacent, pd3dDeviceContext, iDiffuseSlot,
\r
851 iNormalSlot, iSpecularSlot );
\r
854 //--------------------------------------------------------------------------------------
\r
856 //--------------------------------------------------------------------------------------
\r
857 void CDXUTSDKMesh::RenderMesh( UINT iMesh,
\r
858 LPDIRECT3DDEVICE9 pd3dDevice,
\r
859 LPD3DXEFFECT pEffect,
\r
860 D3DXHANDLE hTechnique,
\r
861 D3DXHANDLE htxDiffuse,
\r
862 D3DXHANDLE htxNormal,
\r
863 D3DXHANDLE htxSpecular )
\r
865 if( 0 < GetOutstandingBufferResources() )
\r
868 SDKMESH_MESH* pMesh = &m_pMeshArray[iMesh];
\r
871 for( UINT i = 0; i < ( UINT )pMesh->NumVertexBuffers; i++ )
\r
873 pd3dDevice->SetStreamSource( i,
\r
874 m_pVertexBufferArray[ pMesh->VertexBuffers[i] ].pVB9,
\r
876 ( UINT )m_pVertexBufferArray[ pMesh->VertexBuffers[i] ].StrideBytes );
\r
879 // Set our index buffer as well
\r
880 pd3dDevice->SetIndices( m_pIndexBufferArray[ pMesh->IndexBuffer ].pIB9 );
\r
882 // Render the scene with this technique
\r
883 pEffect->SetTechnique( hTechnique );
\r
885 SDKMESH_SUBSET* pSubset = NULL;
\r
886 SDKMESH_MATERIAL* pMat = NULL;
\r
887 D3DPRIMITIVETYPE PrimType;
\r
889 pEffect->Begin( &cPasses, 0 );
\r
891 for( UINT p = 0; p < cPasses; ++p )
\r
893 pEffect->BeginPass( p );
\r
895 for( UINT subset = 0; subset < pMesh->NumSubsets; subset++ )
\r
897 pSubset = &m_pSubsetArray[ pMesh->pSubsets[subset] ];
\r
899 PrimType = GetPrimitiveType9( ( SDKMESH_PRIMITIVE_TYPE )pSubset->PrimitiveType );
\r
901 if( INVALID_MATERIAL != pSubset->MaterialID && m_pMeshHeader->NumMaterials > 0 )
\r
903 pMat = &m_pMaterialArray[ pSubset->MaterialID ];
\r
904 if( htxDiffuse && !IsErrorResource( pMat->pDiffuseTexture9 ) )
\r
905 pEffect->SetTexture( htxDiffuse, pMat->pDiffuseTexture9 );
\r
906 if( htxNormal && !IsErrorResource( pMat->pNormalTexture9 ) )
\r
907 pEffect->SetTexture( htxNormal, pMat->pNormalTexture9 );
\r
908 if( htxSpecular && !IsErrorResource( pMat->pSpecularTexture9 ) )
\r
909 pEffect->SetTexture( htxSpecular, pMat->pSpecularTexture9 );
\r
912 pEffect->CommitChanges();
\r
914 UINT PrimCount = ( UINT )pSubset->IndexCount;
\r
915 UINT IndexStart = ( UINT )pSubset->IndexStart;
\r
916 UINT VertexStart = ( UINT )pSubset->VertexStart;
\r
917 UINT VertexCount = ( UINT )pSubset->VertexCount;
\r
918 if( D3DPT_TRIANGLELIST == PrimType )
\r
920 if( D3DPT_LINELIST == PrimType )
\r
922 if( D3DPT_TRIANGLESTRIP == PrimType )
\r
923 PrimCount = ( PrimCount - 3 ) + 1;
\r
924 if( D3DPT_LINESTRIP == PrimType )
\r
927 pd3dDevice->DrawIndexedPrimitive( PrimType, VertexStart, 0, VertexCount, IndexStart, PrimCount );
\r
930 pEffect->EndPass();
\r
936 //--------------------------------------------------------------------------------------
\r
937 void CDXUTSDKMesh::RenderFrame( UINT iFrame,
\r
938 LPDIRECT3DDEVICE9 pd3dDevice,
\r
939 LPD3DXEFFECT pEffect,
\r
940 D3DXHANDLE hTechnique,
\r
941 D3DXHANDLE htxDiffuse,
\r
942 D3DXHANDLE htxNormal,
\r
943 D3DXHANDLE htxSpecular )
\r
945 if( !m_pStaticMeshData || !m_pFrameArray )
\r
948 if( m_pFrameArray[iFrame].Mesh != INVALID_MESH )
\r
950 RenderMesh( m_pFrameArray[iFrame].Mesh,
\r
959 // Render our children
\r
960 if( m_pFrameArray[iFrame].ChildFrame != INVALID_FRAME )
\r
961 RenderFrame( m_pFrameArray[iFrame].ChildFrame, pd3dDevice, pEffect, hTechnique, htxDiffuse, htxNormal,
\r
964 // Render our siblings
\r
965 if( m_pFrameArray[iFrame].SiblingFrame != INVALID_FRAME )
\r
966 RenderFrame( m_pFrameArray[iFrame].SiblingFrame, pd3dDevice, pEffect, hTechnique, htxDiffuse, htxNormal,
\r
971 //--------------------------------------------------------------------------------------
\r
972 CDXUTSDKMesh::CDXUTSDKMesh() : m_NumOutstandingResources( 0 ),
\r
973 m_bLoading( false ),
\r
975 m_hFileMappingObject( 0 ),
\r
976 m_pMeshHeader( NULL ),
\r
977 m_pStaticMeshData( NULL ),
\r
978 m_pHeapData( NULL ),
\r
979 m_pAdjacencyIndexBufferArray( NULL ),
\r
980 m_pAnimationData( NULL ),
\r
981 m_pAnimationHeader( NULL ),
\r
982 m_ppVertices( NULL ),
\r
983 m_ppIndices( NULL ),
\r
984 m_pBindPoseFrameMatrices( NULL ),
\r
985 m_pTransformedFrameMatrices( NULL ),
\r
986 m_pWorldPoseFrameMatrices( NULL ),
\r
993 //--------------------------------------------------------------------------------------
\r
994 CDXUTSDKMesh::~CDXUTSDKMesh()
\r
999 //--------------------------------------------------------------------------------------
\r
1000 HRESULT CDXUTSDKMesh::Create( ID3D11Device* pDev11, LPCTSTR szFileName, bool bCreateAdjacencyIndices,
\r
1001 SDKMESH_CALLBACKS11* pLoaderCallbacks )
\r
1003 return CreateFromFile( pDev11, NULL, szFileName, bCreateAdjacencyIndices, pLoaderCallbacks, NULL );
\r
1006 //--------------------------------------------------------------------------------------
\r
1007 HRESULT CDXUTSDKMesh::Create( IDirect3DDevice9* pDev9, LPCTSTR szFileName, bool bCreateAdjacencyIndices,
\r
1008 SDKMESH_CALLBACKS9* pLoaderCallbacks )
\r
1010 return CreateFromFile( NULL, pDev9, szFileName, bCreateAdjacencyIndices, NULL, pLoaderCallbacks );
\r
1013 //--------------------------------------------------------------------------------------
\r
1014 HRESULT CDXUTSDKMesh::Create( ID3D11Device* pDev11, BYTE* pData, UINT DataBytes, bool bCreateAdjacencyIndices,
\r
1015 bool bCopyStatic, SDKMESH_CALLBACKS11* pLoaderCallbacks )
\r
1017 return CreateFromMemory( pDev11, NULL, pData, DataBytes, bCreateAdjacencyIndices, bCopyStatic,
\r
1018 pLoaderCallbacks, NULL );
\r
1022 //--------------------------------------------------------------------------------------
\r
1023 HRESULT CDXUTSDKMesh::Create( IDirect3DDevice9* pDev9, BYTE* pData, UINT DataBytes, bool bCreateAdjacencyIndices,
\r
1024 bool bCopyStatic, SDKMESH_CALLBACKS9* pLoaderCallbacks )
\r
1026 return CreateFromMemory( NULL, pDev9, pData, DataBytes, bCreateAdjacencyIndices, bCopyStatic, NULL,
\r
1027 pLoaderCallbacks );
\r
1030 //--------------------------------------------------------------------------------------
\r
1031 HRESULT CDXUTSDKMesh::LoadAnimation( WCHAR* szFileName )
\r
1033 HRESULT hr = E_FAIL;
\r
1034 DWORD dwBytesRead = 0;
\r
1035 LARGE_INTEGER liMove;
\r
1036 WCHAR strPath[MAX_PATH];
\r
1038 // Find the path for the file
\r
1039 V_RETURN( DXUTFindDXSDKMediaFileCch( strPath, MAX_PATH, szFileName ) );
\r
1042 HANDLE hFile = CreateFile( strPath, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING,
\r
1043 FILE_FLAG_SEQUENTIAL_SCAN, NULL );
\r
1044 if( INVALID_HANDLE_VALUE == hFile )
\r
1045 return DXUTERR_MEDIANOTFOUND;
\r
1047 /////////////////////////
\r
1049 SDKANIMATION_FILE_HEADER fileheader;
\r
1050 if( !ReadFile( hFile, &fileheader, sizeof( SDKANIMATION_FILE_HEADER ), &dwBytesRead, NULL ) )
\r
1054 m_pAnimationData = new BYTE[ ( size_t )( sizeof( SDKANIMATION_FILE_HEADER ) + fileheader.AnimationDataSize ) ];
\r
1055 if( !m_pAnimationData )
\r
1057 hr = E_OUTOFMEMORY;
\r
1062 liMove.QuadPart = 0;
\r
1063 if( !SetFilePointerEx( hFile, liMove, NULL, FILE_BEGIN ) )
\r
1065 if( !ReadFile( hFile, m_pAnimationData, ( DWORD )( sizeof( SDKANIMATION_FILE_HEADER ) +
\r
1066 fileheader.AnimationDataSize ), &dwBytesRead, NULL ) )
\r
1070 m_pAnimationHeader = ( SDKANIMATION_FILE_HEADER* )m_pAnimationData;
\r
1071 m_pAnimationFrameData = ( SDKANIMATION_FRAME_DATA* )( m_pAnimationData + m_pAnimationHeader->AnimationDataOffset );
\r
1073 UINT64 BaseOffset = sizeof( SDKANIMATION_FILE_HEADER );
\r
1074 for( UINT i = 0; i < m_pAnimationHeader->NumFrames; i++ )
\r
1076 m_pAnimationFrameData[i].pAnimationData = ( SDKANIMATION_DATA* )( m_pAnimationData +
\r
1077 m_pAnimationFrameData[i].DataOffset +
\r
1079 SDKMESH_FRAME* pFrame = FindFrame( m_pAnimationFrameData[i].FrameName );
\r
1082 pFrame->AnimationDataIndex = i;
\r
1088 CloseHandle( hFile );
\r
1092 //--------------------------------------------------------------------------------------
\r
1093 void CDXUTSDKMesh::Destroy()
\r
1095 if( !CheckLoadDone() )
\r
1098 if( m_pStaticMeshData )
\r
1100 if( m_pMaterialArray )
\r
1102 for( UINT64 m = 0; m < m_pMeshHeader->NumMaterials; m++ )
\r
1106 if( !IsErrorResource( m_pMaterialArray[m].pDiffuseTexture9 ) )
\r
1107 SAFE_RELEASE( m_pMaterialArray[m].pDiffuseTexture9 );
\r
1108 if( !IsErrorResource( m_pMaterialArray[m].pNormalTexture9 ) )
\r
1109 SAFE_RELEASE( m_pMaterialArray[m].pNormalTexture9 );
\r
1110 if( !IsErrorResource( m_pMaterialArray[m].pSpecularTexture9 ) )
\r
1111 SAFE_RELEASE( m_pMaterialArray[m].pSpecularTexture9 );
\r
1113 else if( m_pDev11 )
\r
1115 //ID3D11Resource* pRes = NULL;
\r
1116 if( m_pMaterialArray[m].pDiffuseRV11 && !IsErrorResource( m_pMaterialArray[m].pDiffuseRV11 ) )
\r
1118 //m_pMaterialArray[m].pDiffuseRV11->GetResource( &pRes );
\r
1119 //SAFE_RELEASE( pRes );
\r
1121 SAFE_RELEASE( m_pMaterialArray[m].pDiffuseRV11 );
\r
1123 if( m_pMaterialArray[m].pNormalRV11 && !IsErrorResource( m_pMaterialArray[m].pNormalRV11 ) )
\r
1125 //m_pMaterialArray[m].pNormalRV11->GetResource( &pRes );
\r
1126 //SAFE_RELEASE( pRes );
\r
1128 SAFE_RELEASE( m_pMaterialArray[m].pNormalRV11 );
\r
1130 if( m_pMaterialArray[m].pSpecularRV11 && !IsErrorResource( m_pMaterialArray[m].pSpecularRV11 ) )
\r
1132 //m_pMaterialArray[m].pSpecularRV11->GetResource( &pRes );
\r
1133 //SAFE_RELEASE( pRes );
\r
1135 SAFE_RELEASE( m_pMaterialArray[m].pSpecularRV11 );
\r
1141 for( UINT64 i = 0; i < m_pMeshHeader->NumVertexBuffers; i++ )
\r
1143 if( !IsErrorResource( m_pVertexBufferArray[i].pVB9 ) )
\r
1144 SAFE_RELEASE( m_pVertexBufferArray[i].pVB9 );
\r
1147 for( UINT64 i = 0; i < m_pMeshHeader->NumIndexBuffers; i++ )
\r
1149 if( !IsErrorResource( m_pIndexBufferArray[i].pIB9 ) )
\r
1150 SAFE_RELEASE( m_pIndexBufferArray[i].pIB9 );
\r
1154 if( m_pAdjacencyIndexBufferArray )
\r
1156 for( UINT64 i = 0; i < m_pMeshHeader->NumIndexBuffers; i++ )
\r
1158 SAFE_RELEASE( m_pAdjacencyIndexBufferArray[i].pIB11 );
\r
1161 SAFE_DELETE_ARRAY( m_pAdjacencyIndexBufferArray );
\r
1163 SAFE_DELETE_ARRAY( m_pHeapData );
\r
1164 m_pStaticMeshData = NULL;
\r
1165 SAFE_DELETE_ARRAY( m_pAnimationData );
\r
1166 SAFE_DELETE_ARRAY( m_pBindPoseFrameMatrices );
\r
1167 SAFE_DELETE_ARRAY( m_pTransformedFrameMatrices );
\r
1168 SAFE_DELETE_ARRAY( m_pWorldPoseFrameMatrices );
\r
1170 SAFE_DELETE_ARRAY( m_ppVertices );
\r
1171 SAFE_DELETE_ARRAY( m_ppIndices );
\r
1173 m_pMeshHeader = NULL;
\r
1174 m_pVertexBufferArray = NULL;
\r
1175 m_pIndexBufferArray = NULL;
\r
1176 m_pMeshArray = NULL;
\r
1177 m_pSubsetArray = NULL;
\r
1178 m_pFrameArray = NULL;
\r
1179 m_pMaterialArray = NULL;
\r
1181 m_pAnimationHeader = NULL;
\r
1182 m_pAnimationFrameData = NULL;
\r
1186 //--------------------------------------------------------------------------------------
\r
1187 // transform the bind pose
\r
1188 //--------------------------------------------------------------------------------------
\r
1189 void CDXUTSDKMesh::TransformBindPose( D3DXMATRIX* pWorld )
\r
1191 TransformBindPoseFrame( 0, pWorld );
\r
1194 //--------------------------------------------------------------------------------------
\r
1195 // transform the mesh frames according to the animation for time fTime
\r
1196 //--------------------------------------------------------------------------------------
\r
1197 void CDXUTSDKMesh::TransformMesh( D3DXMATRIX* pWorld, double fTime )
\r
1199 if( m_pAnimationHeader == NULL || FTT_RELATIVE == m_pAnimationHeader->FrameTransformType )
\r
1201 TransformFrame( 0, pWorld, fTime );
\r
1203 // For each frame, move the transform to the bind pose, then
\r
1204 // move it to the final position
\r
1205 D3DXMATRIX mInvBindPose;
\r
1206 D3DXMATRIX mFinal;
\r
1207 for( UINT i = 0; i < m_pMeshHeader->NumFrames; i++ )
\r
1209 D3DXMatrixInverse( &mInvBindPose, NULL, &m_pBindPoseFrameMatrices[i] );
\r
1210 mFinal = mInvBindPose * m_pTransformedFrameMatrices[i];
\r
1211 m_pTransformedFrameMatrices[i] = mFinal;
\r
1214 else if( FTT_ABSOLUTE == m_pAnimationHeader->FrameTransformType )
\r
1216 for( UINT i = 0; i < m_pAnimationHeader->NumFrames; i++ )
\r
1217 TransformFrameAbsolute( i, fTime );
\r
1222 //--------------------------------------------------------------------------------------
\r
1223 void CDXUTSDKMesh::Render( ID3D11DeviceContext* pd3dDeviceContext,
\r
1224 UINT iDiffuseSlot,
\r
1226 UINT iSpecularSlot )
\r
1228 RenderFrame( 0, false, pd3dDeviceContext, iDiffuseSlot, iNormalSlot, iSpecularSlot );
\r
1231 //--------------------------------------------------------------------------------------
\r
1232 void CDXUTSDKMesh::RenderAdjacent( ID3D11DeviceContext* pd3dDeviceContext,
\r
1233 UINT iDiffuseSlot,
\r
1235 UINT iSpecularSlot )
\r
1237 RenderFrame( 0, true, pd3dDeviceContext, iDiffuseSlot, iNormalSlot, iSpecularSlot );
\r
1241 //--------------------------------------------------------------------------------------
\r
1242 void CDXUTSDKMesh::Render( LPDIRECT3DDEVICE9 pd3dDevice,
\r
1243 LPD3DXEFFECT pEffect,
\r
1244 D3DXHANDLE hTechnique,
\r
1245 D3DXHANDLE htxDiffuse,
\r
1246 D3DXHANDLE htxNormal,
\r
1247 D3DXHANDLE htxSpecular )
\r
1249 RenderFrame( 0, pd3dDevice, pEffect, hTechnique, htxDiffuse, htxNormal, htxSpecular );
\r
1252 //--------------------------------------------------------------------------------------
\r
1253 D3D11_PRIMITIVE_TOPOLOGY CDXUTSDKMesh::GetPrimitiveType11( SDKMESH_PRIMITIVE_TYPE PrimType )
\r
1255 D3D11_PRIMITIVE_TOPOLOGY retType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
\r
1257 switch( PrimType )
\r
1259 case PT_TRIANGLE_LIST:
\r
1260 retType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
\r
1262 case PT_TRIANGLE_STRIP:
\r
1263 retType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
\r
1265 case PT_LINE_LIST:
\r
1266 retType = D3D11_PRIMITIVE_TOPOLOGY_LINELIST;
\r
1268 case PT_LINE_STRIP:
\r
1269 retType = D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP;
\r
1271 case PT_POINT_LIST:
\r
1272 retType = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
\r
1274 case PT_TRIANGLE_LIST_ADJ:
\r
1275 retType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ;
\r
1277 case PT_TRIANGLE_STRIP_ADJ:
\r
1278 retType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ;
\r
1280 case PT_LINE_LIST_ADJ:
\r
1281 retType = D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ;
\r
1283 case PT_LINE_STRIP_ADJ:
\r
1284 retType = D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ;
\r
1291 //--------------------------------------------------------------------------------------
\r
1292 DXGI_FORMAT CDXUTSDKMesh::GetIBFormat11( UINT iMesh )
\r
1294 switch( m_pIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].IndexType )
\r
1297 return DXGI_FORMAT_R16_UINT;
\r
1299 return DXGI_FORMAT_R32_UINT;
\r
1301 return DXGI_FORMAT_R16_UINT;
\r
1304 //--------------------------------------------------------------------------------------
\r
1305 ID3D11Buffer* CDXUTSDKMesh::GetVB11( UINT iMesh, UINT iVB )
\r
1307 return m_pVertexBufferArray[ m_pMeshArray[ iMesh ].VertexBuffers[iVB] ].pVB11;
\r
1310 //--------------------------------------------------------------------------------------
\r
1311 ID3D11Buffer* CDXUTSDKMesh::GetIB11( UINT iMesh )
\r
1313 return m_pIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].pIB11;
\r
1315 SDKMESH_INDEX_TYPE CDXUTSDKMesh::GetIndexType( UINT iMesh )
\r
1317 return ( SDKMESH_INDEX_TYPE ) m_pIndexBufferArray[m_pMeshArray[ iMesh ].IndexBuffer].IndexType;
\r
1319 //--------------------------------------------------------------------------------------
\r
1320 ID3D11Buffer* CDXUTSDKMesh::GetAdjIB11( UINT iMesh )
\r
1322 return m_pAdjacencyIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].pIB11;
\r
1325 //--------------------------------------------------------------------------------------
\r
1326 D3DPRIMITIVETYPE CDXUTSDKMesh::GetPrimitiveType9( SDKMESH_PRIMITIVE_TYPE PrimType )
\r
1328 D3DPRIMITIVETYPE retType = D3DPT_TRIANGLELIST;
\r
1330 switch( PrimType )
\r
1332 case PT_TRIANGLE_LIST:
\r
1333 retType = D3DPT_TRIANGLELIST;
\r
1335 case PT_TRIANGLE_STRIP:
\r
1336 retType = D3DPT_TRIANGLESTRIP;
\r
1338 case PT_LINE_LIST:
\r
1339 retType = D3DPT_LINELIST;
\r
1341 case PT_LINE_STRIP:
\r
1342 retType = D3DPT_LINESTRIP;
\r
1344 case PT_POINT_LIST:
\r
1345 retType = D3DPT_POINTLIST;
\r
1352 //--------------------------------------------------------------------------------------
\r
1353 D3DFORMAT CDXUTSDKMesh::GetIBFormat9( UINT iMesh )
\r
1355 switch( m_pIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].IndexType )
\r
1358 return D3DFMT_INDEX16;
\r
1360 return D3DFMT_INDEX32;
\r
1362 return D3DFMT_INDEX16;
\r
1365 //--------------------------------------------------------------------------------------
\r
1366 IDirect3DVertexBuffer9* CDXUTSDKMesh::GetVB9( UINT iMesh, UINT iVB )
\r
1368 return m_pVertexBufferArray[ m_pMeshArray[ iMesh ].VertexBuffers[iVB] ].pVB9;
\r
1371 //--------------------------------------------------------------------------------------
\r
1372 IDirect3DIndexBuffer9* CDXUTSDKMesh::GetIB9( UINT iMesh )
\r
1374 return m_pIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].pIB9;
\r
1377 //--------------------------------------------------------------------------------------
\r
1378 char* CDXUTSDKMesh::GetMeshPathA()
\r
1383 //--------------------------------------------------------------------------------------
\r
1384 WCHAR* CDXUTSDKMesh::GetMeshPathW()
\r
1386 return m_strPathW;
\r
1389 //--------------------------------------------------------------------------------------
\r
1390 UINT CDXUTSDKMesh::GetNumMeshes()
\r
1392 if( !m_pMeshHeader )
\r
1394 return m_pMeshHeader->NumMeshes;
\r
1397 //--------------------------------------------------------------------------------------
\r
1398 UINT CDXUTSDKMesh::GetNumMaterials()
\r
1400 if( !m_pMeshHeader )
\r
1402 return m_pMeshHeader->NumMaterials;
\r
1405 //--------------------------------------------------------------------------------------
\r
1406 UINT CDXUTSDKMesh::GetNumVBs()
\r
1408 if( !m_pMeshHeader )
\r
1410 return m_pMeshHeader->NumVertexBuffers;
\r
1413 //--------------------------------------------------------------------------------------
\r
1414 UINT CDXUTSDKMesh::GetNumIBs()
\r
1416 if( !m_pMeshHeader )
\r
1418 return m_pMeshHeader->NumIndexBuffers;
\r
1421 //--------------------------------------------------------------------------------------
\r
1422 ID3D11Buffer* CDXUTSDKMesh::GetVB11At( UINT iVB )
\r
1424 return m_pVertexBufferArray[ iVB ].pVB11;
\r
1427 //--------------------------------------------------------------------------------------
\r
1428 ID3D11Buffer* CDXUTSDKMesh::GetIB11At( UINT iIB )
\r
1430 return m_pIndexBufferArray[ iIB ].pIB11;
\r
1433 //--------------------------------------------------------------------------------------
\r
1434 IDirect3DVertexBuffer9* CDXUTSDKMesh::GetVB9At( UINT iVB )
\r
1436 return m_pVertexBufferArray[ iVB ].pVB9;
\r
1439 //--------------------------------------------------------------------------------------
\r
1440 IDirect3DIndexBuffer9* CDXUTSDKMesh::GetIB9At( UINT iIB )
\r
1442 return m_pIndexBufferArray[ iIB ].pIB9;
\r
1445 //--------------------------------------------------------------------------------------
\r
1446 BYTE* CDXUTSDKMesh::GetRawVerticesAt( UINT iVB )
\r
1448 return m_ppVertices[iVB];
\r
1451 //--------------------------------------------------------------------------------------
\r
1452 BYTE* CDXUTSDKMesh::GetRawIndicesAt( UINT iIB )
\r
1454 return m_ppIndices[iIB];
\r
1457 //--------------------------------------------------------------------------------------
\r
1458 SDKMESH_MATERIAL* CDXUTSDKMesh::GetMaterial( UINT iMaterial )
\r
1460 return &m_pMaterialArray[ iMaterial ];
\r
1463 //--------------------------------------------------------------------------------------
\r
1464 SDKMESH_MESH* CDXUTSDKMesh::GetMesh( UINT iMesh )
\r
1466 return &m_pMeshArray[ iMesh ];
\r
1469 //--------------------------------------------------------------------------------------
\r
1470 UINT CDXUTSDKMesh::GetNumSubsets( UINT iMesh )
\r
1472 return m_pMeshArray[ iMesh ].NumSubsets;
\r
1475 //--------------------------------------------------------------------------------------
\r
1476 SDKMESH_SUBSET* CDXUTSDKMesh::GetSubset( UINT iMesh, UINT iSubset )
\r
1478 return &m_pSubsetArray[ m_pMeshArray[ iMesh ].pSubsets[iSubset] ];
\r
1481 //--------------------------------------------------------------------------------------
\r
1482 UINT CDXUTSDKMesh::GetVertexStride( UINT iMesh, UINT iVB )
\r
1484 return ( UINT )m_pVertexBufferArray[ m_pMeshArray[ iMesh ].VertexBuffers[iVB] ].StrideBytes;
\r
1487 //--------------------------------------------------------------------------------------
\r
1488 UINT CDXUTSDKMesh::GetNumFrames()
\r
1490 return m_pMeshHeader->NumFrames;
\r
1493 //--------------------------------------------------------------------------------------
\r
1494 SDKMESH_FRAME* CDXUTSDKMesh::GetFrame( UINT iFrame )
\r
1496 assert( iFrame < m_pMeshHeader->NumFrames );
\r
1497 return &m_pFrameArray[ iFrame ];
\r
1500 //--------------------------------------------------------------------------------------
\r
1501 SDKMESH_FRAME* CDXUTSDKMesh::FindFrame( char* pszName )
\r
1503 for( UINT i = 0; i < m_pMeshHeader->NumFrames; i++ )
\r
1505 if( _stricmp( m_pFrameArray[i].Name, pszName ) == 0 )
\r
1507 return &m_pFrameArray[i];
\r
1513 //--------------------------------------------------------------------------------------
\r
1514 UINT64 CDXUTSDKMesh::GetNumVertices( UINT iMesh, UINT iVB )
\r
1516 return m_pVertexBufferArray[ m_pMeshArray[ iMesh ].VertexBuffers[iVB] ].NumVertices;
\r
1519 //--------------------------------------------------------------------------------------
\r
1520 UINT64 CDXUTSDKMesh::GetNumIndices( UINT iMesh )
\r
1522 return m_pIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].NumIndices;
\r
1525 //--------------------------------------------------------------------------------------
\r
1526 D3DXVECTOR3 CDXUTSDKMesh::GetMeshBBoxCenter( UINT iMesh )
\r
1528 return m_pMeshArray[iMesh].BoundingBoxCenter;
\r
1531 //--------------------------------------------------------------------------------------
\r
1532 D3DXVECTOR3 CDXUTSDKMesh::GetMeshBBoxExtents( UINT iMesh )
\r
1534 return m_pMeshArray[iMesh].BoundingBoxExtents;
\r
1537 //--------------------------------------------------------------------------------------
\r
1538 UINT CDXUTSDKMesh::GetOutstandingResources()
\r
1540 UINT outstandingResources = 0;
\r
1541 if( !m_pMeshHeader )
\r
1544 outstandingResources += GetOutstandingBufferResources();
\r
1548 for( UINT i = 0; i < m_pMeshHeader->NumMaterials; i++ )
\r
1550 if( m_pMaterialArray[i].DiffuseTexture[0] != 0 )
\r
1552 if( !m_pMaterialArray[i].pDiffuseRV11 && !IsErrorResource( m_pMaterialArray[i].pDiffuseRV11 ) )
\r
1553 outstandingResources ++;
\r
1556 if( m_pMaterialArray[i].NormalTexture[0] != 0 )
\r
1558 if( !m_pMaterialArray[i].pNormalRV11 && !IsErrorResource( m_pMaterialArray[i].pNormalRV11 ) )
\r
1559 outstandingResources ++;
\r
1562 if( m_pMaterialArray[i].SpecularTexture[0] != 0 )
\r
1564 if( !m_pMaterialArray[i].pSpecularRV11 && !IsErrorResource( m_pMaterialArray[i].pSpecularRV11 ) )
\r
1565 outstandingResources ++;
\r
1571 for( UINT i = 0; i < m_pMeshHeader->NumMaterials; i++ )
\r
1573 if( m_pMaterialArray[i].DiffuseTexture[0] != 0 )
\r
1575 if( !m_pMaterialArray[i].pDiffuseTexture9 && !IsErrorResource( m_pMaterialArray[i].pDiffuseTexture9 ) )
\r
1576 outstandingResources ++;
\r
1579 if( m_pMaterialArray[i].NormalTexture[0] != 0 )
\r
1581 if( !m_pMaterialArray[i].pNormalTexture9 && !IsErrorResource( m_pMaterialArray[i].pNormalTexture9 ) )
\r
1582 outstandingResources ++;
\r
1585 if( m_pMaterialArray[i].SpecularTexture[0] != 0 )
\r
1587 if( !m_pMaterialArray[i].pSpecularTexture9 &&
\r
1588 !IsErrorResource( m_pMaterialArray[i].pSpecularTexture9 ) )
\r
1589 outstandingResources ++;
\r
1594 return outstandingResources;
\r
1597 //--------------------------------------------------------------------------------------
\r
1598 UINT CDXUTSDKMesh::GetOutstandingBufferResources()
\r
1600 UINT outstandingResources = 0;
\r
1601 if( !m_pMeshHeader )
\r
1604 for( UINT i = 0; i < m_pMeshHeader->NumVertexBuffers; i++ )
\r
1606 if( !m_pVertexBufferArray[i].pVB9 && !IsErrorResource( m_pVertexBufferArray[i].pVB9 ) )
\r
1607 outstandingResources ++;
\r
1610 for( UINT i = 0; i < m_pMeshHeader->NumIndexBuffers; i++ )
\r
1612 if( !m_pIndexBufferArray[i].pIB9 && !IsErrorResource( m_pIndexBufferArray[i].pIB9 ) )
\r
1613 outstandingResources ++;
\r
1616 return outstandingResources;
\r
1619 //--------------------------------------------------------------------------------------
\r
1620 bool CDXUTSDKMesh::CheckLoadDone()
\r
1622 if( 0 == GetOutstandingResources() )
\r
1624 m_bLoading = false;
\r
1631 //--------------------------------------------------------------------------------------
\r
1632 bool CDXUTSDKMesh::IsLoaded()
\r
1634 if( m_pStaticMeshData && !m_bLoading )
\r
1642 //--------------------------------------------------------------------------------------
\r
1643 bool CDXUTSDKMesh::IsLoading()
\r
1645 return m_bLoading;
\r
1648 //--------------------------------------------------------------------------------------
\r
1649 void CDXUTSDKMesh::SetLoading( bool bLoading )
\r
1651 m_bLoading = bLoading;
\r
1654 //--------------------------------------------------------------------------------------
\r
1655 BOOL CDXUTSDKMesh::HadLoadingError()
\r
1657 if( m_pMeshHeader )
\r
1659 for( UINT i = 0; i < m_pMeshHeader->NumVertexBuffers; i++ )
\r
1661 if( IsErrorResource( m_pVertexBufferArray[i].pVB9 ) )
\r
1665 for( UINT i = 0; i < m_pMeshHeader->NumIndexBuffers; i++ )
\r
1667 if( IsErrorResource( m_pIndexBufferArray[i].pIB9 ) )
\r
1675 //--------------------------------------------------------------------------------------
\r
1676 UINT CDXUTSDKMesh::GetNumInfluences( UINT iMesh )
\r
1678 return m_pMeshArray[iMesh].NumFrameInfluences;
\r
1681 //--------------------------------------------------------------------------------------
\r
1682 const D3DXMATRIX* CDXUTSDKMesh::GetMeshInfluenceMatrix( UINT iMesh, UINT iInfluence )
\r
1684 UINT iFrame = m_pMeshArray[iMesh].pFrameInfluences[ iInfluence ];
\r
1685 return &m_pTransformedFrameMatrices[iFrame];
\r
1688 const D3DXMATRIX* CDXUTSDKMesh::GetWorldMatrix( UINT iFrameIndex )
\r
1690 return &m_pWorldPoseFrameMatrices[iFrameIndex];
\r
1693 const D3DXMATRIX* CDXUTSDKMesh::GetInfluenceMatrix( UINT iFrameIndex )
\r
1695 return &m_pTransformedFrameMatrices[iFrameIndex];
\r
1698 //--------------------------------------------------------------------------------------
\r
1699 UINT CDXUTSDKMesh::GetAnimationKeyFromTime( double fTime )
\r
1701 if( m_pAnimationHeader == NULL )
\r
1706 UINT iTick = ( UINT )( m_pAnimationHeader->AnimationFPS * fTime );
\r
1708 iTick = iTick % ( m_pAnimationHeader->NumAnimationKeys - 1 );
\r
1714 bool CDXUTSDKMesh::GetAnimationProperties( UINT* pNumKeys, FLOAT* pFrameTime )
\r
1716 if( m_pAnimationHeader == NULL )
\r
1721 *pNumKeys = m_pAnimationHeader->NumAnimationKeys;
\r
1722 *pFrameTime = 1.0f / (FLOAT)m_pAnimationHeader->AnimationFPS;
\r
1728 //-------------------------------------------------------------------------------------
\r
1729 // CDXUTXFileMesh implementation.
\r
1730 //-------------------------------------------------------------------------------------
\r
1732 //-----------------------------------------------------------------------------
\r
1733 CDXUTXFileMesh::CDXUTXFileMesh( LPCWSTR strName )
\r
1735 wcscpy_s( m_strName, 512, strName );
\r
1737 m_pMaterials = NULL;
\r
1738 m_pTextures = NULL;
\r
1739 m_bUseMaterials = TRUE;
\r
1743 m_strMaterials = NULL;
\r
1744 m_dwNumMaterials = 0;
\r
1745 m_dwNumVertices = 0;
\r
1747 m_dwBytesPerVertex = 0;
\r
1753 //-----------------------------------------------------------------------------
\r
1754 CDXUTXFileMesh::~CDXUTXFileMesh()
\r
1762 //-----------------------------------------------------------------------------
\r
1763 HRESULT CDXUTXFileMesh::Create( LPDIRECT3DDEVICE9 pd3dDevice, LPCWSTR strFilename )
\r
1765 WCHAR strPath[MAX_PATH];
\r
1766 LPD3DXBUFFER pAdjacencyBuffer = NULL;
\r
1767 LPD3DXBUFFER pMtrlBuffer = NULL;
\r
1770 // Cleanup previous mesh if any
\r
1773 // Find the path for the file, and convert it to ANSI (for the D3DX API)
\r
1774 DXUTFindDXSDKMediaFileCch( strPath, sizeof( strPath ) / sizeof( WCHAR ), strFilename );
\r
1777 if( FAILED( hr = D3DXLoadMeshFromX( strPath, D3DXMESH_MANAGED, pd3dDevice,
\r
1778 &pAdjacencyBuffer, &pMtrlBuffer, NULL,
\r
1779 &m_dwNumMaterials, &m_pMesh ) ) )
\r
1784 // Optimize the mesh for performance
\r
1785 if( FAILED( hr = m_pMesh->OptimizeInplace(
\r
1786 D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,
\r
1787 ( DWORD* )pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ) ) )
\r
1789 SAFE_RELEASE( pAdjacencyBuffer );
\r
1790 SAFE_RELEASE( pMtrlBuffer );
\r
1794 // Set strPath to the path of the mesh file
\r
1795 WCHAR* pLastBSlash = wcsrchr( strPath, L'\\' );
\r
1797 *( pLastBSlash + 1 ) = L'\0';
\r
1801 D3DXMATERIAL* d3dxMtrls = ( D3DXMATERIAL* )pMtrlBuffer->GetBufferPointer();
\r
1802 hr = CreateMaterials( strPath, pd3dDevice, d3dxMtrls, m_dwNumMaterials );
\r
1804 SAFE_RELEASE( pAdjacencyBuffer );
\r
1805 SAFE_RELEASE( pMtrlBuffer );
\r
1807 // Extract data from m_pMesh for easy access
\r
1808 D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];
\r
1809 m_dwNumVertices = m_pMesh->GetNumVertices();
\r
1810 m_dwNumFaces = m_pMesh->GetNumFaces();
\r
1811 m_dwBytesPerVertex = m_pMesh->GetNumBytesPerVertex();
\r
1812 m_pMesh->GetIndexBuffer( &m_pIB );
\r
1813 m_pMesh->GetVertexBuffer( &m_pVB );
\r
1814 m_pMesh->GetDeclaration( decl );
\r
1815 pd3dDevice->CreateVertexDeclaration( decl, &m_pDecl );
\r
1821 //-----------------------------------------------------------------------------
\r
1822 HRESULT CDXUTXFileMesh::Create( LPDIRECT3DDEVICE9 pd3dDevice,
\r
1823 LPD3DXFILEDATA pFileData )
\r
1825 LPD3DXBUFFER pMtrlBuffer = NULL;
\r
1826 LPD3DXBUFFER pAdjacencyBuffer = NULL;
\r
1829 // Cleanup previous mesh if any
\r
1832 // Load the mesh from the DXFILEDATA object
\r
1833 if( FAILED( hr = D3DXLoadMeshFromXof( pFileData, D3DXMESH_MANAGED, pd3dDevice,
\r
1834 &pAdjacencyBuffer, &pMtrlBuffer, NULL,
\r
1835 &m_dwNumMaterials, &m_pMesh ) ) )
\r
1840 // Optimize the mesh for performance
\r
1841 if( FAILED( hr = m_pMesh->OptimizeInplace(
\r
1842 D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE,
\r
1843 ( DWORD* )pAdjacencyBuffer->GetBufferPointer(), NULL, NULL, NULL ) ) )
\r
1845 SAFE_RELEASE( pAdjacencyBuffer );
\r
1846 SAFE_RELEASE( pMtrlBuffer );
\r
1850 D3DXMATERIAL* d3dxMtrls = ( D3DXMATERIAL* )pMtrlBuffer->GetBufferPointer();
\r
1851 hr = CreateMaterials( L"", pd3dDevice, d3dxMtrls, m_dwNumMaterials );
\r
1853 SAFE_RELEASE( pAdjacencyBuffer );
\r
1854 SAFE_RELEASE( pMtrlBuffer );
\r
1856 // Extract data from m_pMesh for easy access
\r
1857 D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];
\r
1858 m_dwNumVertices = m_pMesh->GetNumVertices();
\r
1859 m_dwNumFaces = m_pMesh->GetNumFaces();
\r
1860 m_dwBytesPerVertex = m_pMesh->GetNumBytesPerVertex();
\r
1861 m_pMesh->GetIndexBuffer( &m_pIB );
\r
1862 m_pMesh->GetVertexBuffer( &m_pVB );
\r
1863 m_pMesh->GetDeclaration( decl );
\r
1864 pd3dDevice->CreateVertexDeclaration( decl, &m_pDecl );
\r
1870 //-----------------------------------------------------------------------------
\r
1871 HRESULT CDXUTXFileMesh::Create( LPDIRECT3DDEVICE9 pd3dDevice, ID3DXMesh* pInMesh,
\r
1872 D3DXMATERIAL* pd3dxMaterials, DWORD dwMaterials )
\r
1874 // Cleanup previous mesh if any
\r
1877 // Optimize the mesh for performance
\r
1878 DWORD* rgdwAdjacency = NULL;
\r
1879 rgdwAdjacency = new DWORD[pInMesh->GetNumFaces() * 3];
\r
1880 if( rgdwAdjacency == NULL )
\r
1881 return E_OUTOFMEMORY;
\r
1882 pInMesh->GenerateAdjacency( 1e-6f, rgdwAdjacency );
\r
1884 D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];
\r
1885 pInMesh->GetDeclaration( decl );
\r
1887 DWORD dwOptions = pInMesh->GetOptions();
\r
1888 dwOptions &= ~( D3DXMESH_32BIT | D3DXMESH_SYSTEMMEM | D3DXMESH_WRITEONLY );
\r
1889 dwOptions |= D3DXMESH_MANAGED;
\r
1890 dwOptions |= D3DXMESHOPT_COMPACT | D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_VERTEXCACHE;
\r
1892 ID3DXMesh* pTempMesh = NULL;
\r
1893 if( FAILED( pInMesh->Optimize( dwOptions, rgdwAdjacency, NULL, NULL, NULL, &pTempMesh ) ) )
\r
1895 SAFE_DELETE_ARRAY( rgdwAdjacency );
\r
1899 SAFE_DELETE_ARRAY( rgdwAdjacency );
\r
1900 SAFE_RELEASE( m_pMesh );
\r
1901 m_pMesh = pTempMesh;
\r
1904 hr = CreateMaterials( L"", pd3dDevice, pd3dxMaterials, dwMaterials );
\r
1906 // Extract data from m_pMesh for easy access
\r
1907 m_dwNumVertices = m_pMesh->GetNumVertices();
\r
1908 m_dwNumFaces = m_pMesh->GetNumFaces();
\r
1909 m_dwBytesPerVertex = m_pMesh->GetNumBytesPerVertex();
\r
1910 m_pMesh->GetIndexBuffer( &m_pIB );
\r
1911 m_pMesh->GetVertexBuffer( &m_pVB );
\r
1912 m_pMesh->GetDeclaration( decl );
\r
1913 pd3dDevice->CreateVertexDeclaration( decl, &m_pDecl );
\r
1919 //-----------------------------------------------------------------------------
\r
1920 HRESULT CDXUTXFileMesh::CreateMaterials( LPCWSTR strPath, IDirect3DDevice9* pd3dDevice, D3DXMATERIAL* d3dxMtrls,
\r
1921 DWORD dwNumMaterials )
\r
1923 // Get material info for the mesh
\r
1924 // Get the array of materials out of the buffer
\r
1925 m_dwNumMaterials = dwNumMaterials;
\r
1926 if( d3dxMtrls && m_dwNumMaterials > 0 )
\r
1928 // Allocate memory for the materials and textures
\r
1929 m_pMaterials = new D3DMATERIAL9[m_dwNumMaterials];
\r
1930 if( m_pMaterials == NULL )
\r
1931 return E_OUTOFMEMORY;
\r
1932 m_pTextures = new LPDIRECT3DBASETEXTURE9[m_dwNumMaterials];
\r
1933 if( m_pTextures == NULL )
\r
1934 return E_OUTOFMEMORY;
\r
1935 m_strMaterials = new CHAR[m_dwNumMaterials][MAX_PATH];
\r
1936 if( m_strMaterials == NULL )
\r
1937 return E_OUTOFMEMORY;
\r
1939 // Copy each material and create its texture
\r
1940 for( DWORD i = 0; i < m_dwNumMaterials; i++ )
\r
1942 // Copy the material
\r
1943 m_pMaterials[i] = d3dxMtrls[i].MatD3D;
\r
1944 m_pTextures[i] = NULL;
\r
1946 // Create a texture
\r
1947 if( d3dxMtrls[i].pTextureFilename )
\r
1949 strcpy_s( m_strMaterials[i], MAX_PATH, d3dxMtrls[i].pTextureFilename );
\r
1951 WCHAR strTexture[MAX_PATH];
\r
1952 WCHAR strTextureTemp[MAX_PATH];
\r
1953 D3DXIMAGE_INFO ImgInfo;
\r
1955 // First attempt to look for texture in the same folder as the input folder.
\r
1956 MultiByteToWideChar( CP_ACP, 0, d3dxMtrls[i].pTextureFilename, -1, strTextureTemp, MAX_PATH );
\r
1957 strTextureTemp[MAX_PATH - 1] = 0;
\r
1959 wcscpy_s( strTexture, MAX_PATH, strPath );
\r
1960 wcscat_s( strTexture, MAX_PATH, strTextureTemp );
\r
1962 // Inspect the texture file to determine the texture type.
\r
1963 if( FAILED( D3DXGetImageInfoFromFile( strTexture, &ImgInfo ) ) )
\r
1965 // Search the media folder
\r
1966 if( FAILED( DXUTFindDXSDKMediaFileCch( strTexture, MAX_PATH, strTextureTemp ) ) )
\r
1967 continue; // Can't find. Skip.
\r
1969 D3DXGetImageInfoFromFile( strTexture, &ImgInfo );
\r
1972 // Call the appropriate loader according to the texture type.
\r
1973 switch( ImgInfo.ResourceType )
\r
1975 case D3DRTYPE_TEXTURE:
\r
1977 IDirect3DTexture9* pTex;
\r
1978 if( SUCCEEDED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, &pTex ) ) )
\r
1980 // Obtain the base texture interface
\r
1981 pTex->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&m_pTextures[i] );
\r
1982 // Release the specialized instance
\r
1987 case D3DRTYPE_CUBETEXTURE:
\r
1989 IDirect3DCubeTexture9* pTex;
\r
1990 if( SUCCEEDED( D3DXCreateCubeTextureFromFile( pd3dDevice, strTexture, &pTex ) ) )
\r
1992 // Obtain the base texture interface
\r
1993 pTex->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&m_pTextures[i] );
\r
1994 // Release the specialized instance
\r
1999 case D3DRTYPE_VOLUMETEXTURE:
\r
2001 IDirect3DVolumeTexture9* pTex;
\r
2002 if( SUCCEEDED( D3DXCreateVolumeTextureFromFile( pd3dDevice, strTexture, &pTex ) ) )
\r
2004 // Obtain the base texture interface
\r
2005 pTex->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&m_pTextures[i] );
\r
2006 // Release the specialized instance
\r
2019 //-----------------------------------------------------------------------------
\r
2020 HRESULT CDXUTXFileMesh::SetFVF( LPDIRECT3DDEVICE9 pd3dDevice, DWORD dwFVF )
\r
2022 LPD3DXMESH pTempMesh = NULL;
\r
2026 if( FAILED( m_pMesh->CloneMeshFVF( m_pMesh->GetOptions(), dwFVF,
\r
2027 pd3dDevice, &pTempMesh ) ) )
\r
2029 SAFE_RELEASE( pTempMesh );
\r
2033 DWORD dwOldFVF = 0;
\r
2034 dwOldFVF = m_pMesh->GetFVF();
\r
2035 SAFE_RELEASE( m_pMesh );
\r
2036 m_pMesh = pTempMesh;
\r
2038 // Compute normals if they are being requested and
\r
2039 // the old mesh does not have them.
\r
2040 if( !( dwOldFVF & D3DFVF_NORMAL ) && dwFVF & D3DFVF_NORMAL )
\r
2042 D3DXComputeNormals( m_pMesh, NULL );
\r
2052 //-----------------------------------------------------------------------------
\r
2053 // Convert the mesh to the format specified by the given vertex declarations.
\r
2054 //-----------------------------------------------------------------------------
\r
2055 HRESULT CDXUTXFileMesh::SetVertexDecl( LPDIRECT3DDEVICE9 pd3dDevice, const D3DVERTEXELEMENT9* pDecl,
\r
2056 bool bAutoComputeNormals, bool bAutoComputeTangents,
\r
2057 bool bSplitVertexForOptimalTangents )
\r
2059 LPD3DXMESH pTempMesh = NULL;
\r
2063 if( FAILED( m_pMesh->CloneMesh( m_pMesh->GetOptions(), pDecl,
\r
2064 pd3dDevice, &pTempMesh ) ) )
\r
2066 SAFE_RELEASE( pTempMesh );
\r
2072 // Check if the old declaration contains a normal.
\r
2073 bool bHadNormal = false;
\r
2074 bool bHadTangent = false;
\r
2075 D3DVERTEXELEMENT9 aOldDecl[MAX_FVF_DECL_SIZE];
\r
2076 if( m_pMesh && SUCCEEDED( m_pMesh->GetDeclaration( aOldDecl ) ) )
\r
2078 for( UINT index = 0; index < D3DXGetDeclLength( aOldDecl ); ++index )
\r
2080 if( aOldDecl[index].Usage == D3DDECLUSAGE_NORMAL )
\r
2082 bHadNormal = true;
\r
2084 if( aOldDecl[index].Usage == D3DDECLUSAGE_TANGENT )
\r
2086 bHadTangent = true;
\r
2091 // Check if the new declaration contains a normal.
\r
2092 bool bHaveNormalNow = false;
\r
2093 bool bHaveTangentNow = false;
\r
2094 D3DVERTEXELEMENT9 aNewDecl[MAX_FVF_DECL_SIZE];
\r
2095 if( pTempMesh && SUCCEEDED( pTempMesh->GetDeclaration( aNewDecl ) ) )
\r
2097 for( UINT index = 0; index < D3DXGetDeclLength( aNewDecl ); ++index )
\r
2099 if( aNewDecl[index].Usage == D3DDECLUSAGE_NORMAL )
\r
2101 bHaveNormalNow = true;
\r
2103 if( aNewDecl[index].Usage == D3DDECLUSAGE_TANGENT )
\r
2105 bHaveTangentNow = true;
\r
2110 SAFE_RELEASE( m_pMesh );
\r
2114 m_pMesh = pTempMesh;
\r
2116 if( !bHadNormal && bHaveNormalNow && bAutoComputeNormals )
\r
2118 // Compute normals in case the meshes have them
\r
2119 D3DXComputeNormals( m_pMesh, NULL );
\r
2122 if( bHaveNormalNow && !bHadTangent && bHaveTangentNow && bAutoComputeTangents )
\r
2124 ID3DXMesh* pNewMesh;
\r
2127 DWORD* rgdwAdjacency = NULL;
\r
2128 rgdwAdjacency = new DWORD[m_pMesh->GetNumFaces() * 3];
\r
2129 if( rgdwAdjacency == NULL )
\r
2130 return E_OUTOFMEMORY;
\r
2131 V( m_pMesh->GenerateAdjacency( 1e-6f, rgdwAdjacency ) );
\r
2133 float fPartialEdgeThreshold;
\r
2134 float fSingularPointThreshold;
\r
2135 float fNormalEdgeThreshold;
\r
2136 if( bSplitVertexForOptimalTangents )
\r
2138 fPartialEdgeThreshold = 0.01f;
\r
2139 fSingularPointThreshold = 0.25f;
\r
2140 fNormalEdgeThreshold = 0.01f;
\r
2144 fPartialEdgeThreshold = -1.01f;
\r
2145 fSingularPointThreshold = 0.01f;
\r
2146 fNormalEdgeThreshold = -1.01f;
\r
2149 // Compute tangents, which are required for normal mapping
\r
2150 hr = D3DXComputeTangentFrameEx( m_pMesh,
\r
2151 D3DDECLUSAGE_TEXCOORD, 0,
\r
2152 D3DDECLUSAGE_TANGENT, 0,
\r
2154 D3DDECLUSAGE_NORMAL, 0,
\r
2156 fPartialEdgeThreshold, fSingularPointThreshold, fNormalEdgeThreshold,
\r
2157 &pNewMesh, NULL );
\r
2159 SAFE_DELETE_ARRAY( rgdwAdjacency );
\r
2160 if( FAILED( hr ) )
\r
2163 SAFE_RELEASE( m_pMesh );
\r
2164 m_pMesh = pNewMesh;
\r
2174 //-----------------------------------------------------------------------------
\r
2175 HRESULT CDXUTXFileMesh::RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice )
\r
2183 //-----------------------------------------------------------------------------
\r
2184 HRESULT CDXUTXFileMesh::InvalidateDeviceObjects()
\r
2186 SAFE_RELEASE( m_pIB );
\r
2187 SAFE_RELEASE( m_pVB );
\r
2188 SAFE_RELEASE( m_pDecl );
\r
2196 //-----------------------------------------------------------------------------
\r
2197 HRESULT CDXUTXFileMesh::Destroy()
\r
2199 InvalidateDeviceObjects();
\r
2200 for( UINT i = 0; i < m_dwNumMaterials; i++ )
\r
2201 SAFE_RELEASE( m_pTextures[i] );
\r
2202 SAFE_DELETE_ARRAY( m_pTextures );
\r
2203 SAFE_DELETE_ARRAY( m_pMaterials );
\r
2204 SAFE_DELETE_ARRAY( m_strMaterials );
\r
2206 SAFE_RELEASE( m_pMesh );
\r
2208 m_dwNumMaterials = 0L;
\r
2216 //-----------------------------------------------------------------------------
\r
2217 HRESULT CDXUTXFileMesh::Render( LPDIRECT3DDEVICE9 pd3dDevice, bool bDrawOpaqueSubsets,
\r
2218 bool bDrawAlphaSubsets )
\r
2220 if( NULL == m_pMesh )
\r
2223 // Frist, draw the subsets without alpha
\r
2224 if( bDrawOpaqueSubsets )
\r
2226 for( DWORD i = 0; i < m_dwNumMaterials; i++ )
\r
2228 if( m_bUseMaterials )
\r
2230 if( m_pMaterials[i].Diffuse.a < 1.0f )
\r
2232 pd3dDevice->SetMaterial( &m_pMaterials[i] );
\r
2233 pd3dDevice->SetTexture( 0, m_pTextures[i] );
\r
2235 m_pMesh->DrawSubset( i );
\r
2239 // Then, draw the subsets with alpha
\r
2240 if( bDrawAlphaSubsets && m_bUseMaterials )
\r
2242 for( DWORD i = 0; i < m_dwNumMaterials; i++ )
\r
2244 if( m_pMaterials[i].Diffuse.a == 1.0f )
\r
2247 // Set the material and texture
\r
2248 pd3dDevice->SetMaterial( &m_pMaterials[i] );
\r
2249 pd3dDevice->SetTexture( 0, m_pTextures[i] );
\r
2250 m_pMesh->DrawSubset( i );
\r
2260 //-----------------------------------------------------------------------------
\r
2261 HRESULT CDXUTXFileMesh::Render( ID3DXEffect* pEffect,
\r
2262 D3DXHANDLE hTexture,
\r
2263 D3DXHANDLE hDiffuse,
\r
2264 D3DXHANDLE hAmbient,
\r
2265 D3DXHANDLE hSpecular,
\r
2266 D3DXHANDLE hEmissive,
\r
2267 D3DXHANDLE hPower,
\r
2268 bool bDrawOpaqueSubsets,
\r
2269 bool bDrawAlphaSubsets )
\r
2271 if( NULL == m_pMesh )
\r
2275 // Frist, draw the subsets without alpha
\r
2276 if( bDrawOpaqueSubsets )
\r
2278 pEffect->Begin( &cPasses, 0 );
\r
2279 for( UINT p = 0; p < cPasses; ++p )
\r
2281 pEffect->BeginPass( p );
\r
2282 for( DWORD i = 0; i < m_dwNumMaterials; i++ )
\r
2284 if( m_bUseMaterials )
\r
2286 if( m_pMaterials[i].Diffuse.a < 1.0f )
\r
2289 pEffect->SetTexture( hTexture, m_pTextures[i] );
\r
2290 // D3DCOLORVALUE and D3DXVECTOR4 are data-wise identical.
\r
2291 // No conversion is needed.
\r
2293 pEffect->SetVector( hDiffuse, ( D3DXVECTOR4* )&m_pMaterials[i].Diffuse );
\r
2295 pEffect->SetVector( hAmbient, ( D3DXVECTOR4* )&m_pMaterials[i].Ambient );
\r
2297 pEffect->SetVector( hSpecular, ( D3DXVECTOR4* )&m_pMaterials[i].Specular );
\r
2299 pEffect->SetVector( hEmissive, ( D3DXVECTOR4* )&m_pMaterials[i].Emissive );
\r
2301 pEffect->SetFloat( hPower, m_pMaterials[i].Power );
\r
2302 pEffect->CommitChanges();
\r
2304 m_pMesh->DrawSubset( i );
\r
2306 pEffect->EndPass();
\r
2311 // Then, draw the subsets with alpha
\r
2312 if( bDrawAlphaSubsets && m_bUseMaterials )
\r
2314 pEffect->Begin( &cPasses, 0 );
\r
2315 for( UINT p = 0; p < cPasses; ++p )
\r
2317 pEffect->BeginPass( p );
\r
2318 for( DWORD i = 0; i < m_dwNumMaterials; i++ )
\r
2320 if( m_bUseMaterials )
\r
2322 if( m_pMaterials[i].Diffuse.a == 1.0f )
\r
2325 pEffect->SetTexture( hTexture, m_pTextures[i] );
\r
2326 // D3DCOLORVALUE and D3DXVECTOR4 are data-wise identical.
\r
2327 // No conversion is needed.
\r
2329 pEffect->SetVector( hDiffuse, ( D3DXVECTOR4* )&m_pMaterials[i].Diffuse );
\r
2331 pEffect->SetVector( hAmbient, ( D3DXVECTOR4* )&m_pMaterials[i].Ambient );
\r
2333 pEffect->SetVector( hSpecular, ( D3DXVECTOR4* )&m_pMaterials[i].Specular );
\r
2335 pEffect->SetVector( hEmissive, ( D3DXVECTOR4* )&m_pMaterials[i].Emissive );
\r
2337 pEffect->SetFloat( hPower, m_pMaterials[i].Power );
\r
2338 pEffect->CommitChanges();
\r
2340 m_pMesh->DrawSubset( i );
\r
2342 pEffect->EndPass();
\r