Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Demos / DX11ClothDemo / DXUT / Optional / SDKmesh.cpp
1 //--------------------------------------------------------------------------------------\r
2 // File: SDKMesh.cpp\r
3 //\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
8 //\r
9 // Copyright (c) Microsoft Corporation. All rights reserved.\r
10 //--------------------------------------------------------------------------------------\r
11 #include "DXUT.h"\r
12 #include "SDKMesh.h"\r
13 #include "SDKMisc.h"\r
14 \r
15 //--------------------------------------------------------------------------------------\r
16 void CDXUTSDKMesh::LoadMaterials( ID3D11Device* pd3dDevice, SDKMESH_MATERIAL* pMaterials, UINT numMaterials,\r
17                                   SDKMESH_CALLBACKS11* pLoaderCallbacks )\r
18 {\r
19     // TODO: D3D11\r
20     char strPath[MAX_PATH];\r
21 \r
22     if( pLoaderCallbacks && pLoaderCallbacks->pCreateTextureFromFile )\r
23     {\r
24         for( UINT m = 0; m < numMaterials; m++ )\r
25         {\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
32 \r
33             // load textures\r
34             if( pMaterials[m].DiffuseTexture[0] != 0 )\r
35             {\r
36                 pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice,\r
37                                                           pMaterials[m].DiffuseTexture, &pMaterials[m].pDiffuseRV11,\r
38                                                           pLoaderCallbacks->pContext );\r
39             }\r
40             if( pMaterials[m].NormalTexture[0] != 0 )\r
41             {\r
42                 pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice,\r
43                                                           pMaterials[m].NormalTexture, &pMaterials[m].pNormalRV11,\r
44                                                           pLoaderCallbacks->pContext );\r
45             }\r
46             if( pMaterials[m].SpecularTexture[0] != 0 )\r
47             {\r
48                 pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice,\r
49                                                           pMaterials[m].SpecularTexture, &pMaterials[m].pSpecularRV11,\r
50                                                           pLoaderCallbacks->pContext );\r
51             }\r
52         }\r
53     }\r
54     else\r
55     {\r
56         for( UINT m = 0; m < numMaterials; m++ )\r
57         {\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
64 \r
65             // load textures\r
66             if( pMaterials[m].DiffuseTexture[0] != 0 )\r
67             {\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
71                                                                                 true ) ) )\r
72                     pMaterials[m].pDiffuseRV11 = ( ID3D11ShaderResourceView* )ERROR_RESOURCE_VALUE;\r
73 \r
74             }\r
75             if( pMaterials[m].NormalTexture[0] != 0 )\r
76             {\r
77                 sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].NormalTexture );\r
78                 if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice, DXUTGetD3D11DeviceContext(),\r
79                                                                                 strPath,\r
80                                                                                 &pMaterials[m].pNormalRV11 ) ) )\r
81                     pMaterials[m].pNormalRV11 = ( ID3D11ShaderResourceView* )ERROR_RESOURCE_VALUE;\r
82             }\r
83             if( pMaterials[m].SpecularTexture[0] != 0 )\r
84             {\r
85                 sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].SpecularTexture );\r
86                 if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice, DXUTGetD3D11DeviceContext(),\r
87                                                                                 strPath,\r
88                                                                                 &pMaterials[m].pSpecularRV11 ) ) )\r
89                     pMaterials[m].pSpecularRV11 = ( ID3D11ShaderResourceView* )ERROR_RESOURCE_VALUE;\r
90             }\r
91         }\r
92     }\r
93 }\r
94 \r
95 //--------------------------------------------------------------------------------------\r
96 void CDXUTSDKMesh::LoadMaterials( IDirect3DDevice9* pd3dDevice, SDKMESH_MATERIAL* pMaterials, UINT numMaterials,\r
97                                   SDKMESH_CALLBACKS9* pLoaderCallbacks )\r
98 {\r
99     char strPath[MAX_PATH];\r
100 \r
101     if( pLoaderCallbacks && pLoaderCallbacks->pCreateTextureFromFile )\r
102     {\r
103         for( UINT m = 0; m < numMaterials; m++ )\r
104         {\r
105             pMaterials[m].pDiffuseTexture9 = NULL;\r
106             pMaterials[m].pNormalTexture9 = NULL;\r
107             pMaterials[m].pSpecularTexture9 = NULL;\r
108 \r
109             // load textures\r
110             if( pMaterials[m].DiffuseTexture[0] != 0 )\r
111             {\r
112                 pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice,\r
113                                                           pMaterials[m].DiffuseTexture,\r
114                                                           &pMaterials[m].pDiffuseTexture9,\r
115                                                           pLoaderCallbacks->pContext );\r
116             }\r
117             if( pMaterials[m].NormalTexture[0] != 0 )\r
118             {\r
119                 pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice,\r
120                                                           pMaterials[m].NormalTexture, &pMaterials[m].pNormalTexture9,\r
121                                                           pLoaderCallbacks->pContext );\r
122             }\r
123             if( pMaterials[m].SpecularTexture[0] != 0 )\r
124             {\r
125                 pLoaderCallbacks->pCreateTextureFromFile( pd3dDevice,\r
126                                                           pMaterials[m].SpecularTexture,\r
127                                                           &pMaterials[m].pSpecularTexture9,\r
128                                                           pLoaderCallbacks->pContext );\r
129             }\r
130         }\r
131     }\r
132     else\r
133     {\r
134         for( UINT m = 0; m < numMaterials; m++ )\r
135         {\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
142 \r
143             // load textures\r
144             if( pMaterials[m].DiffuseTexture[0] != 0 )\r
145             {\r
146                 sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].DiffuseTexture );\r
147                 if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice,\r
148                                                                                 strPath,\r
149                                                                                 &pMaterials[m].pDiffuseTexture9 ) ) )\r
150                     pMaterials[m].pDiffuseTexture9 = ( IDirect3DTexture9* )ERROR_RESOURCE_VALUE;\r
151             }\r
152             if( pMaterials[m].NormalTexture[0] != 0 )\r
153             {\r
154                 sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].NormalTexture );\r
155                 if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice,\r
156                                                                                 strPath,\r
157                                                                                 &pMaterials[m].pNormalTexture9 ) ) )\r
158                     pMaterials[m].pNormalTexture9 = ( IDirect3DTexture9* )ERROR_RESOURCE_VALUE;\r
159             }\r
160             if( pMaterials[m].SpecularTexture[0] != 0 )\r
161             {\r
162                 sprintf_s( strPath, MAX_PATH, "%s%s", m_strPath, pMaterials[m].SpecularTexture );\r
163                 if( FAILED( DXUTGetGlobalResourceCache().CreateTextureFromFile( pd3dDevice,\r
164                                                                                 strPath,\r
165                                                                                 &pMaterials[m].pSpecularTexture9 ) ) )\r
166                     pMaterials[m].pSpecularTexture9 = ( IDirect3DTexture9* )ERROR_RESOURCE_VALUE;\r
167             }\r
168 \r
169         }\r
170     }\r
171 }\r
172 \r
173 //--------------------------------------------------------------------------------------\r
174 HRESULT CDXUTSDKMesh::CreateVertexBuffer( ID3D11Device* pd3dDevice, SDKMESH_VERTEX_BUFFER_HEADER* pHeader,\r
175                                           void* pVertices, SDKMESH_CALLBACKS11* pLoaderCallbacks )\r
176 {\r
177     HRESULT hr = S_OK;\r
178     pHeader->DataOffset = 0;\r
179     //Vertex Buffer\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
186 \r
187     if( pLoaderCallbacks && pLoaderCallbacks->pCreateVertexBuffer )\r
188     {\r
189         pLoaderCallbacks->pCreateVertexBuffer( pd3dDevice, &pHeader->pVB11, bufferDesc, pVertices,\r
190                                                pLoaderCallbacks->pContext );\r
191     }\r
192     else\r
193     {\r
194         D3D11_SUBRESOURCE_DATA InitData;\r
195         InitData.pSysMem = pVertices;\r
196         hr = pd3dDevice->CreateBuffer( &bufferDesc, &InitData, &pHeader->pVB11 );\r
197     }\r
198 \r
199     return hr;\r
200 }\r
201 \r
202 \r
203 //--------------------------------------------------------------------------------------\r
204 HRESULT CDXUTSDKMesh::CreateIndexBuffer( ID3D11Device* pd3dDevice, SDKMESH_INDEX_BUFFER_HEADER* pHeader,\r
205                                          void* pIndices, SDKMESH_CALLBACKS11* pLoaderCallbacks )\r
206 {\r
207     HRESULT hr = S_OK;\r
208     pHeader->DataOffset = 0;\r
209     //Index Buffer\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
216 \r
217     if( pLoaderCallbacks && pLoaderCallbacks->pCreateIndexBuffer )\r
218     {\r
219         pLoaderCallbacks->pCreateIndexBuffer( pd3dDevice, &pHeader->pIB11, bufferDesc, pIndices,\r
220                                               pLoaderCallbacks->pContext );\r
221     }\r
222     else\r
223     {\r
224         D3D11_SUBRESOURCE_DATA InitData;\r
225         InitData.pSysMem = pIndices;\r
226         hr = pd3dDevice->CreateBuffer( &bufferDesc, &InitData, &pHeader->pIB11 );\r
227     }\r
228 \r
229     return hr;\r
230 }\r
231 \r
232 \r
233 //--------------------------------------------------------------------------------------\r
234 HRESULT CDXUTSDKMesh::CreateVertexBuffer( IDirect3DDevice9* pd3dDevice, SDKMESH_VERTEX_BUFFER_HEADER* pHeader,\r
235                                           void* pVertices, SDKMESH_CALLBACKS9* pLoaderCallbacks )\r
236 {\r
237     HRESULT hr = S_OK;\r
238 \r
239     pHeader->DataOffset = 0;\r
240     if( pLoaderCallbacks && pLoaderCallbacks->pCreateVertexBuffer )\r
241     {\r
242         pLoaderCallbacks->pCreateVertexBuffer( pd3dDevice, &pHeader->pVB9, ( UINT )pHeader->SizeBytes,\r
243                                                D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, pVertices,\r
244                                                pLoaderCallbacks->pContext );\r
245     }\r
246     else\r
247     {\r
248         hr = pd3dDevice->CreateVertexBuffer( ( UINT )pHeader->SizeBytes,\r
249                                              D3DUSAGE_WRITEONLY,\r
250                                              0,\r
251                                              D3DPOOL_DEFAULT,\r
252                                              &pHeader->pVB9,\r
253                                              NULL );\r
254 \r
255         //lock\r
256         if( SUCCEEDED( hr ) )\r
257         {\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
262         }\r
263     }\r
264 \r
265     return hr;\r
266 }\r
267 \r
268 //--------------------------------------------------------------------------------------\r
269 HRESULT CDXUTSDKMesh::CreateIndexBuffer( IDirect3DDevice9* pd3dDevice, SDKMESH_INDEX_BUFFER_HEADER* pHeader,\r
270                                          void* pIndices, SDKMESH_CALLBACKS9* pLoaderCallbacks )\r
271 {\r
272     HRESULT hr = S_OK;\r
273 \r
274     pHeader->DataOffset = 0;\r
275 \r
276     D3DFORMAT ibFormat = D3DFMT_INDEX16;\r
277     switch( pHeader->IndexType )\r
278     {\r
279         case IT_16BIT:\r
280             ibFormat = D3DFMT_INDEX16;\r
281             break;\r
282         case IT_32BIT:\r
283             ibFormat = D3DFMT_INDEX32;\r
284             break;\r
285     };\r
286 \r
287     if( pLoaderCallbacks && pLoaderCallbacks->pCreateIndexBuffer )\r
288     {\r
289         pLoaderCallbacks->pCreateIndexBuffer( pd3dDevice, &pHeader->pIB9, ( UINT )pHeader->SizeBytes,\r
290                                               D3DUSAGE_WRITEONLY, ibFormat, D3DPOOL_DEFAULT, pIndices,\r
291                                               pLoaderCallbacks->pContext );\r
292     }\r
293     else\r
294     {\r
295         hr = pd3dDevice->CreateIndexBuffer( ( UINT )( pHeader->SizeBytes ),\r
296                                             D3DUSAGE_WRITEONLY,\r
297                                             ibFormat,\r
298                                             D3DPOOL_DEFAULT,\r
299                                             &pHeader->pIB9,\r
300                                             NULL );\r
301 \r
302         if( SUCCEEDED( hr ) )\r
303         {\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
308         }\r
309     }\r
310 \r
311     return hr;\r
312 }\r
313 \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
321 {\r
322     HRESULT hr = S_OK;\r
323 \r
324     // Find the path for the file\r
325     V_RETURN( DXUTFindDXSDKMediaFileCch( m_strPathW, sizeof( m_strPathW ) / sizeof( WCHAR ), szFileName ) );\r
326 \r
327     // Open the file\r
328     m_hFile = CreateFile( m_strPathW, FILE_READ_DATA, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN,\r
329                           NULL );\r
330     if( INVALID_HANDLE_VALUE == m_hFile )\r
331         return DXUTERR_MEDIANOTFOUND;\r
332 \r
333     // Change the path to just the directory\r
334     WCHAR* pLastBSlash = wcsrchr( m_strPathW, L'\\' );\r
335     if( pLastBSlash )\r
336         *( pLastBSlash + 1 ) = L'\0';\r
337     else\r
338         *m_strPathW = L'\0';\r
339 \r
340     WideCharToMultiByte( CP_ACP, 0, m_strPathW, -1, m_strPath, MAX_PATH, NULL, FALSE );\r
341 \r
342     // Get the file size\r
343     LARGE_INTEGER FileSize;\r
344     GetFileSizeEx( m_hFile, &FileSize );\r
345     UINT cBytes = FileSize.LowPart;\r
346 \r
347     // Allocate memory\r
348     m_pStaticMeshData = new BYTE[ cBytes ];\r
349     if( !m_pStaticMeshData )\r
350     {\r
351         CloseHandle( m_hFile );\r
352         return E_OUTOFMEMORY;\r
353     }\r
354 \r
355     // Read in the file\r
356     DWORD dwBytesRead;\r
357     if( !ReadFile( m_hFile, m_pStaticMeshData, cBytes, &dwBytesRead, NULL ) )\r
358         hr = E_FAIL;\r
359 \r
360     CloseHandle( m_hFile );\r
361 \r
362     if( SUCCEEDED( hr ) )\r
363     {\r
364         hr = CreateFromMemory( pDev11,\r
365                                pDev9,\r
366                                m_pStaticMeshData,\r
367                                cBytes,\r
368                                bCreateAdjacencyIndices,\r
369                                false,\r
370                                pLoaderCallbacks11,\r
371                                pLoaderCallbacks9 );\r
372         if( FAILED( hr ) )\r
373             delete []m_pStaticMeshData;\r
374     }\r
375 \r
376     return hr;\r
377 }\r
378 \r
379 HRESULT CDXUTSDKMesh::CreateFromMemory( ID3D11Device* pDev11,\r
380                                         IDirect3DDevice9* pDev9,\r
381                                         BYTE* pData,\r
382                                         UINT DataBytes,\r
383                                         bool bCreateAdjacencyIndices,\r
384                                         bool bCopyStatic,\r
385                                         SDKMESH_CALLBACKS11* pLoaderCallbacks11,\r
386                                         SDKMESH_CALLBACKS9* pLoaderCallbacks9 )\r
387 {\r
388     HRESULT hr = E_FAIL;\r
389     D3DXVECTOR3 lower; \r
390     D3DXVECTOR3 upper; \r
391     \r
392     m_pDev9 = pDev9;\r
393         m_pDev11 = pDev11;\r
394 \r
395     // Set outstanding resources to zero\r
396     m_NumOutstandingResources = 0;\r
397 \r
398     if( bCopyStatic )\r
399     {\r
400         SDKMESH_HEADER* pHeader = ( SDKMESH_HEADER* )pData;\r
401 \r
402         SIZE_T StaticSize = ( SIZE_T )( pHeader->HeaderSize + pHeader->NonBufferDataSize );\r
403         m_pHeapData = new BYTE[ StaticSize ];\r
404         if( !m_pHeapData )\r
405             return hr;\r
406 \r
407         m_pStaticMeshData = m_pHeapData;\r
408 \r
409         CopyMemory( m_pStaticMeshData, pData, StaticSize );\r
410     }\r
411     else\r
412     {\r
413         m_pHeapData = pData;\r
414         m_pStaticMeshData = pData;\r
415     }\r
416 \r
417     // Pointer fixup\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
427 \r
428     // Setup subsets\r
429     for( UINT i = 0; i < m_pMeshHeader->NumMeshes; i++ )\r
430     {\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
433     }\r
434 \r
435     // error condition\r
436     if( m_pMeshHeader->Version != SDKMESH_FILE_VERSION )\r
437     {\r
438         hr = E_NOINTERFACE;\r
439         goto Error;\r
440     }\r
441 \r
442     // Setup buffer data pointer\r
443     BYTE* pBufferData = pData + m_pMeshHeader->HeaderSize + m_pMeshHeader->NonBufferDataSize;\r
444 \r
445     // Get the start of the buffer data\r
446     UINT64 BufferDataStart = m_pMeshHeader->HeaderSize + m_pMeshHeader->NonBufferDataSize;\r
447 \r
448     // Create VBs\r
449     m_ppVertices = new BYTE*[m_pMeshHeader->NumVertexBuffers];\r
450     for( UINT i = 0; i < m_pMeshHeader->NumVertexBuffers; i++ )\r
451     {\r
452         BYTE* pVertices = NULL;\r
453         pVertices = ( BYTE* )( pBufferData + ( m_pVertexBufferArray[i].DataOffset - BufferDataStart ) );\r
454 \r
455         if( pDev11 )\r
456             CreateVertexBuffer( pDev11, &m_pVertexBufferArray[i], pVertices, pLoaderCallbacks11 );\r
457         else if( pDev9 )\r
458             CreateVertexBuffer( pDev9, &m_pVertexBufferArray[i], pVertices, pLoaderCallbacks9 );\r
459 \r
460         m_ppVertices[i] = pVertices;\r
461     }\r
462 \r
463     // Create IBs\r
464     m_ppIndices = new BYTE*[m_pMeshHeader->NumIndexBuffers];\r
465     for( UINT i = 0; i < m_pMeshHeader->NumIndexBuffers; i++ )\r
466     {\r
467         BYTE* pIndices = NULL;\r
468         pIndices = ( BYTE* )( pBufferData + ( m_pIndexBufferArray[i].DataOffset - BufferDataStart ) );\r
469 \r
470         if( pDev11 )\r
471             CreateIndexBuffer( pDev11, &m_pIndexBufferArray[i], pIndices, pLoaderCallbacks11 );\r
472         else if( pDev9 )\r
473             CreateIndexBuffer( pDev9, &m_pIndexBufferArray[i], pIndices, pLoaderCallbacks9 );\r
474 \r
475         m_ppIndices[i] = pIndices;\r
476     }\r
477 \r
478     // Load Materials\r
479     if( pDev11 )\r
480         LoadMaterials( pDev11, m_pMaterialArray, m_pMeshHeader->NumMaterials, pLoaderCallbacks11 );\r
481     else if( pDev9 )\r
482         LoadMaterials( pDev9, m_pMaterialArray, m_pMeshHeader->NumMaterials, pLoaderCallbacks9 );\r
483 \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
487         goto Error;\r
488 \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
492         goto Error;\r
493     m_pWorldPoseFrameMatrices = new D3DXMATRIX[ m_pMeshHeader->NumFrames ];\r
494     if( !m_pWorldPoseFrameMatrices )\r
495         goto Error;\r
496 \r
497     SDKMESH_SUBSET* pSubset = NULL;\r
498     D3D11_PRIMITIVE_TOPOLOGY PrimType;\r
499 \r
500     // update bounding volume \r
501     SDKMESH_MESH* currentMesh = &m_pMeshArray[0];\r
502     int tris = 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
507         INT indsize;\r
508         if (m_pIndexBufferArray[currentMesh->IndexBuffer].IndexType == IT_16BIT ) {\r
509             indsize = 2;\r
510         }else {\r
511             indsize = 4;        \r
512         }\r
513 \r
514         for( UINT subset = 0; subset < currentMesh->NumSubsets; subset++ )\r
515         {\r
516             pSubset = GetSubset( meshi, subset ); //&m_pSubsetArray[ currentMesh->pSubsets[subset] ];\r
517 \r
518             PrimType = GetPrimitiveType11( ( SDKMESH_PRIMITIVE_TYPE )pSubset->PrimitiveType );\r
519             assert( PrimType == D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );// only triangle lists are handled.\r
520 \r
521             UINT IndexCount = ( UINT )pSubset->IndexCount;\r
522             UINT IndexStart = ( UINT )pSubset->IndexStart;\r
523 \r
524             /*if( bAdjacent )\r
525             {\r
526                 IndexCount *= 2;\r
527                 IndexStart *= 2;\r
528             }*/\r
529      \r
530         //BYTE* pIndices = NULL;\r
531             //m_ppIndices[i]\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
536             stride /=4;\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
545                     }else {\r
546                         current_ind = current_ind >> 16;\r
547                     }\r
548                 }else {\r
549                     current_ind = ind[vertind];\r
550                 }\r
551                 tris++;\r
552                 D3DXVECTOR3 *pt = (D3DXVECTOR3*)&(verts[stride * current_ind]);\r
553                 if (pt->x < lower.x) {\r
554                     lower.x = pt->x;\r
555                 }\r
556                 if (pt->y < lower.y) {\r
557                     lower.y = pt->y;\r
558                 }\r
559                 if (pt->z < lower.z) {\r
560                     lower.z = pt->z;\r
561                 }\r
562                 if (pt->x > upper.x) {\r
563                     upper.x = pt->x;\r
564                 }\r
565                 if (pt->y > upper.y) {\r
566                     upper.y = pt->y;\r
567                 }\r
568                 if (pt->z > upper.z) {\r
569                     upper.z = pt->z;\r
570                 }\r
571                 //BYTE** m_ppVertices;\r
572                 //BYTE** m_ppIndices;\r
573             }\r
574             //pd3dDeviceContext->DrawIndexed( IndexCount, IndexStart, VertexStart );\r
575         }\r
576 \r
577         D3DXVECTOR3 half = upper - lower;\r
578         half *=0.5f;\r
579 \r
580         currentMesh->BoundingBoxCenter = lower + half;\r
581         currentMesh->BoundingBoxExtents = half;\r
582 \r
583     }\r
584     // Update \r
585         \r
586 \r
587 \r
588     hr = S_OK;\r
589 Error:\r
590 \r
591     if( !pLoaderCallbacks9 )\r
592     {\r
593         CheckLoadDone();\r
594     }\r
595 \r
596     return hr;\r
597 }\r
598 \r
599 //--------------------------------------------------------------------------------------\r
600 // transform bind pose frame using a recursive traversal\r
601 //--------------------------------------------------------------------------------------\r
602 void CDXUTSDKMesh::TransformBindPoseFrame( UINT iFrame, D3DXMATRIX* pParentWorld )\r
603 {\r
604     if( !m_pBindPoseFrameMatrices )\r
605         return;\r
606 \r
607     // Transform ourselves\r
608     D3DXMATRIX LocalWorld;\r
609     D3DXMatrixMultiply( &LocalWorld, &m_pFrameArray[iFrame].Matrix, pParentWorld );\r
610     m_pBindPoseFrameMatrices[iFrame] = LocalWorld;\r
611 \r
612     // Transform our siblings\r
613     if( m_pFrameArray[iFrame].SiblingFrame != INVALID_FRAME )\r
614         TransformBindPoseFrame( m_pFrameArray[iFrame].SiblingFrame, pParentWorld );\r
615 \r
616     // Transform our children\r
617     if( m_pFrameArray[iFrame].ChildFrame != INVALID_FRAME )\r
618         TransformBindPoseFrame( m_pFrameArray[iFrame].ChildFrame, &LocalWorld );\r
619 }\r
620 \r
621 //--------------------------------------------------------------------------------------\r
622 // transform frame using a recursive traversal\r
623 //--------------------------------------------------------------------------------------\r
624 void CDXUTSDKMesh::TransformFrame( UINT iFrame, D3DXMATRIX* pParentWorld, double fTime )\r
625 {\r
626     // Get the tick data\r
627     D3DXMATRIX LocalTransform;\r
628     UINT iTick = GetAnimationKeyFromTime( fTime );\r
629 \r
630     if( INVALID_ANIMATION_DATA != m_pFrameArray[iFrame].AnimationDataIndex )\r
631     {\r
632         SDKANIMATION_FRAME_DATA* pFrameData = &m_pAnimationFrameData[ m_pFrameArray[iFrame].AnimationDataIndex ];\r
633         SDKANIMATION_DATA* pData = &pFrameData->pAnimationData[ iTick ];\r
634 \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
639 \r
640         D3DXQUATERNION quat;\r
641         D3DXMATRIX mQuat;\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
651     }\r
652     else\r
653     {\r
654         LocalTransform = m_pFrameArray[iFrame].Matrix;\r
655     }\r
656 \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
662 \r
663     // Transform our siblings\r
664     if( m_pFrameArray[iFrame].SiblingFrame != INVALID_FRAME )\r
665         TransformFrame( m_pFrameArray[iFrame].SiblingFrame, pParentWorld, fTime );\r
666 \r
667     // Transform our children\r
668     if( m_pFrameArray[iFrame].ChildFrame != INVALID_FRAME )\r
669         TransformFrame( m_pFrameArray[iFrame].ChildFrame, &LocalWorld, fTime );\r
670 }\r
671 \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
676 {\r
677     D3DXMATRIX mTrans1;\r
678     D3DXMATRIX mTrans2;\r
679     D3DXMATRIX mRot1;\r
680     D3DXMATRIX mRot2;\r
681     D3DXQUATERNION quat1;\r
682     D3DXQUATERNION quat2;\r
683     D3DXMATRIX mTo;\r
684     D3DXMATRIX mInvTo;\r
685     D3DXMATRIX mFrom;\r
686 \r
687     UINT iTick = GetAnimationKeyFromTime( fTime );\r
688 \r
689     if( INVALID_ANIMATION_DATA != m_pFrameArray[iFrame].AnimationDataIndex )\r
690     {\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
694 \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
701 \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
709 \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
716 \r
717         D3DXMATRIX mOutput = mInvTo * mFrom;\r
718         m_pTransformedFrameMatrices[iFrame] = mOutput;\r
719     }\r
720 }\r
721 \r
722 #define MAX_D3D11_VERTEX_STREAMS D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT\r
723 //--------------------------------------------------------------------------------------\r
724 void CDXUTSDKMesh::RenderMesh( UINT iMesh,\r
725                                bool bAdjacent,\r
726                                ID3D11DeviceContext* pd3dDeviceContext,\r
727                                UINT iDiffuseSlot,\r
728                                UINT iNormalSlot,\r
729                                UINT iSpecularSlot )\r
730 {\r
731     if( 0 < GetOutstandingBufferResources() )\r
732         return;\r
733 \r
734     SDKMESH_MESH* pMesh = &m_pMeshArray[iMesh];\r
735 \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
739 \r
740     if( pMesh->NumVertexBuffers > MAX_D3D11_VERTEX_STREAMS )\r
741         return;\r
742 \r
743     for( UINT64 i = 0; i < pMesh->NumVertexBuffers; i++ )\r
744     {\r
745         pVB[i] = m_pVertexBufferArray[ pMesh->VertexBuffers[i] ].pVB11;\r
746         Strides[i] = ( UINT )m_pVertexBufferArray[ pMesh->VertexBuffers[i] ].StrideBytes;\r
747         Offsets[i] = 0;\r
748     }\r
749 \r
750     SDKMESH_INDEX_BUFFER_HEADER* pIndexBufferArray;\r
751     if( bAdjacent )\r
752         pIndexBufferArray = m_pAdjacencyIndexBufferArray;\r
753     else\r
754         pIndexBufferArray = m_pIndexBufferArray;\r
755 \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
759     {\r
760     case IT_16BIT:\r
761         ibFormat = DXGI_FORMAT_R16_UINT;\r
762         break;\r
763     case IT_32BIT:\r
764         ibFormat = DXGI_FORMAT_R32_UINT;\r
765         break;\r
766     };\r
767 \r
768     pd3dDeviceContext->IASetVertexBuffers( 0, pMesh->NumVertexBuffers, pVB, Strides, Offsets );\r
769     pd3dDeviceContext->IASetIndexBuffer( pIB, ibFormat, 0 );\r
770 \r
771     SDKMESH_SUBSET* pSubset = NULL;\r
772     SDKMESH_MATERIAL* pMat = NULL;\r
773     D3D11_PRIMITIVE_TOPOLOGY PrimType;\r
774 \r
775     for( UINT subset = 0; subset < pMesh->NumSubsets; subset++ )\r
776     {\r
777         pSubset = &m_pSubsetArray[ pMesh->pSubsets[subset] ];\r
778 \r
779         PrimType = GetPrimitiveType11( ( SDKMESH_PRIMITIVE_TYPE )pSubset->PrimitiveType );\r
780         if( bAdjacent )\r
781         {\r
782             switch( PrimType )\r
783             {\r
784             case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST:\r
785                 PrimType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ;\r
786                 break;\r
787             case D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP:\r
788                 PrimType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ;\r
789                 break;\r
790             case D3D11_PRIMITIVE_TOPOLOGY_LINELIST:\r
791                 PrimType = D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ;\r
792                 break;\r
793             case D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP:\r
794                 PrimType = D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ;\r
795                 break;\r
796             }\r
797         }\r
798 \r
799         pd3dDeviceContext->IASetPrimitiveTopology( PrimType );\r
800 \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
808 \r
809         UINT IndexCount = ( UINT )pSubset->IndexCount;\r
810         UINT IndexStart = ( UINT )pSubset->IndexStart;\r
811         UINT VertexStart = ( UINT )pSubset->VertexStart;\r
812         if( bAdjacent )\r
813         {\r
814             IndexCount *= 2;\r
815             IndexStart *= 2;\r
816         }\r
817 \r
818         pd3dDeviceContext->DrawIndexed( IndexCount, IndexStart, VertexStart );\r
819     }\r
820 }\r
821 \r
822 //--------------------------------------------------------------------------------------\r
823 void CDXUTSDKMesh::RenderFrame( UINT iFrame,\r
824                                 bool bAdjacent,\r
825                                 ID3D11DeviceContext* pd3dDeviceContext,\r
826                                 UINT iDiffuseSlot,\r
827                                 UINT iNormalSlot,\r
828                                 UINT iSpecularSlot )\r
829 {\r
830     if( !m_pStaticMeshData || !m_pFrameArray )\r
831         return;\r
832 \r
833     if( m_pFrameArray[iFrame].Mesh != INVALID_MESH )\r
834     {\r
835         RenderMesh( m_pFrameArray[iFrame].Mesh,\r
836                     bAdjacent,\r
837                     pd3dDeviceContext,\r
838                     iDiffuseSlot,\r
839                     iNormalSlot,\r
840                     iSpecularSlot );\r
841     }\r
842 \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
847 \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
852 }\r
853 \r
854 //--------------------------------------------------------------------------------------\r
855 \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
864 {\r
865     if( 0 < GetOutstandingBufferResources() )\r
866         return;\r
867 \r
868     SDKMESH_MESH* pMesh = &m_pMeshArray[iMesh];\r
869 \r
870     // set vb streams\r
871     for( UINT i = 0; i < ( UINT )pMesh->NumVertexBuffers; i++ )\r
872     {\r
873         pd3dDevice->SetStreamSource( i,\r
874                                      m_pVertexBufferArray[ pMesh->VertexBuffers[i] ].pVB9,\r
875                                      0,\r
876                                      ( UINT )m_pVertexBufferArray[ pMesh->VertexBuffers[i] ].StrideBytes );\r
877     }\r
878 \r
879     // Set our index buffer as well\r
880     pd3dDevice->SetIndices( m_pIndexBufferArray[ pMesh->IndexBuffer ].pIB9 );\r
881 \r
882     // Render the scene with this technique \r
883     pEffect->SetTechnique( hTechnique );\r
884 \r
885     SDKMESH_SUBSET* pSubset = NULL;\r
886     SDKMESH_MATERIAL* pMat = NULL;\r
887     D3DPRIMITIVETYPE PrimType;\r
888     UINT cPasses = 0;\r
889     pEffect->Begin( &cPasses, 0 );\r
890 \r
891     for( UINT p = 0; p < cPasses; ++p )\r
892     {\r
893         pEffect->BeginPass( p );\r
894 \r
895         for( UINT subset = 0; subset < pMesh->NumSubsets; subset++ )\r
896         {\r
897             pSubset = &m_pSubsetArray[ pMesh->pSubsets[subset] ];\r
898 \r
899             PrimType = GetPrimitiveType9( ( SDKMESH_PRIMITIVE_TYPE )pSubset->PrimitiveType );\r
900 \r
901             if( INVALID_MATERIAL != pSubset->MaterialID && m_pMeshHeader->NumMaterials > 0 )\r
902             {\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
910             }\r
911 \r
912             pEffect->CommitChanges();\r
913 \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
919                 PrimCount /= 3;\r
920             if( D3DPT_LINELIST == PrimType )\r
921                 PrimCount /= 2;\r
922             if( D3DPT_TRIANGLESTRIP == PrimType )\r
923                 PrimCount = ( PrimCount - 3 ) + 1;\r
924             if( D3DPT_LINESTRIP == PrimType )\r
925                 PrimCount -= 1;\r
926 \r
927             pd3dDevice->DrawIndexedPrimitive( PrimType, VertexStart, 0, VertexCount, IndexStart, PrimCount );\r
928         }\r
929 \r
930         pEffect->EndPass();\r
931     }\r
932 \r
933     pEffect->End();\r
934 }\r
935 \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
944 {\r
945     if( !m_pStaticMeshData || !m_pFrameArray )\r
946         return;\r
947 \r
948     if( m_pFrameArray[iFrame].Mesh != INVALID_MESH )\r
949     {\r
950         RenderMesh( m_pFrameArray[iFrame].Mesh,\r
951                     pd3dDevice,\r
952                     pEffect,\r
953                     hTechnique,\r
954                     htxDiffuse,\r
955                     htxNormal,\r
956                     htxSpecular );\r
957     }\r
958 \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
962                      htxSpecular );\r
963 \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
967                      htxSpecular );\r
968 }\r
969 \r
970 \r
971 //--------------------------------------------------------------------------------------\r
972 CDXUTSDKMesh::CDXUTSDKMesh() : m_NumOutstandingResources( 0 ),\r
973                                m_bLoading( false ),\r
974                                m_hFile( 0 ),\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
987                                m_pDev9( NULL ),\r
988                                                            m_pDev11( NULL )\r
989 {\r
990 }\r
991 \r
992 \r
993 //--------------------------------------------------------------------------------------\r
994 CDXUTSDKMesh::~CDXUTSDKMesh()\r
995 {\r
996     Destroy();\r
997 }\r
998 \r
999 //--------------------------------------------------------------------------------------\r
1000 HRESULT CDXUTSDKMesh::Create( ID3D11Device* pDev11, LPCTSTR szFileName, bool bCreateAdjacencyIndices,\r
1001                               SDKMESH_CALLBACKS11* pLoaderCallbacks )\r
1002 {\r
1003     return CreateFromFile( pDev11,  NULL, szFileName, bCreateAdjacencyIndices, pLoaderCallbacks,  NULL );\r
1004 }\r
1005 \r
1006 //--------------------------------------------------------------------------------------\r
1007 HRESULT CDXUTSDKMesh::Create( IDirect3DDevice9* pDev9, LPCTSTR szFileName, bool bCreateAdjacencyIndices,\r
1008                               SDKMESH_CALLBACKS9* pLoaderCallbacks )\r
1009 {\r
1010     return CreateFromFile( NULL,  pDev9, szFileName, bCreateAdjacencyIndices, NULL,  pLoaderCallbacks );\r
1011 }\r
1012 \r
1013 //--------------------------------------------------------------------------------------\r
1014 HRESULT CDXUTSDKMesh::Create( ID3D11Device* pDev11, BYTE* pData, UINT DataBytes, bool bCreateAdjacencyIndices,\r
1015                               bool bCopyStatic, SDKMESH_CALLBACKS11* pLoaderCallbacks )\r
1016 {\r
1017     return CreateFromMemory( pDev11, NULL, pData, DataBytes, bCreateAdjacencyIndices, bCopyStatic,\r
1018                              pLoaderCallbacks,  NULL );\r
1019 }\r
1020 \r
1021 \r
1022 //--------------------------------------------------------------------------------------\r
1023 HRESULT CDXUTSDKMesh::Create( IDirect3DDevice9* pDev9, BYTE* pData, UINT DataBytes, bool bCreateAdjacencyIndices,\r
1024                               bool bCopyStatic, SDKMESH_CALLBACKS9* pLoaderCallbacks )\r
1025 {\r
1026     return CreateFromMemory( NULL, pDev9, pData, DataBytes, bCreateAdjacencyIndices, bCopyStatic, NULL, \r
1027                              pLoaderCallbacks );\r
1028 }\r
1029 \r
1030 //--------------------------------------------------------------------------------------\r
1031 HRESULT CDXUTSDKMesh::LoadAnimation( WCHAR* szFileName )\r
1032 {\r
1033     HRESULT hr = E_FAIL;\r
1034     DWORD dwBytesRead = 0;\r
1035     LARGE_INTEGER liMove;\r
1036     WCHAR strPath[MAX_PATH];\r
1037 \r
1038     // Find the path for the file\r
1039     V_RETURN( DXUTFindDXSDKMediaFileCch( strPath, MAX_PATH, szFileName ) );\r
1040 \r
1041     // Open the file\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
1046 \r
1047     /////////////////////////\r
1048     // Header\r
1049     SDKANIMATION_FILE_HEADER fileheader;\r
1050     if( !ReadFile( hFile, &fileheader, sizeof( SDKANIMATION_FILE_HEADER ), &dwBytesRead, NULL ) )\r
1051         goto Error;\r
1052 \r
1053     //allocate\r
1054     m_pAnimationData = new BYTE[ ( size_t )( sizeof( SDKANIMATION_FILE_HEADER ) + fileheader.AnimationDataSize ) ];\r
1055     if( !m_pAnimationData )\r
1056     {\r
1057         hr = E_OUTOFMEMORY;\r
1058         goto Error;\r
1059     }\r
1060 \r
1061     // read it all in\r
1062     liMove.QuadPart = 0;\r
1063     if( !SetFilePointerEx( hFile, liMove, NULL, FILE_BEGIN ) )\r
1064         goto Error;\r
1065     if( !ReadFile( hFile, m_pAnimationData, ( DWORD )( sizeof( SDKANIMATION_FILE_HEADER ) +\r
1066                                                        fileheader.AnimationDataSize ), &dwBytesRead, NULL ) )\r
1067         goto Error;\r
1068 \r
1069     // pointer fixup\r
1070     m_pAnimationHeader = ( SDKANIMATION_FILE_HEADER* )m_pAnimationData;\r
1071     m_pAnimationFrameData = ( SDKANIMATION_FRAME_DATA* )( m_pAnimationData + m_pAnimationHeader->AnimationDataOffset );\r
1072 \r
1073     UINT64 BaseOffset = sizeof( SDKANIMATION_FILE_HEADER );\r
1074     for( UINT i = 0; i < m_pAnimationHeader->NumFrames; i++ )\r
1075     {\r
1076         m_pAnimationFrameData[i].pAnimationData = ( SDKANIMATION_DATA* )( m_pAnimationData +\r
1077                                                                           m_pAnimationFrameData[i].DataOffset +\r
1078                                                                           BaseOffset );\r
1079         SDKMESH_FRAME* pFrame = FindFrame( m_pAnimationFrameData[i].FrameName );\r
1080         if( pFrame )\r
1081         {\r
1082             pFrame->AnimationDataIndex = i;\r
1083         }\r
1084     }\r
1085 \r
1086     hr = S_OK;\r
1087 Error:\r
1088     CloseHandle( hFile );\r
1089     return hr;\r
1090 }\r
1091 \r
1092 //--------------------------------------------------------------------------------------\r
1093 void CDXUTSDKMesh::Destroy()\r
1094 {\r
1095     if( !CheckLoadDone() )\r
1096         return;\r
1097 \r
1098     if( m_pStaticMeshData )\r
1099     {\r
1100         if( m_pMaterialArray )\r
1101         {\r
1102             for( UINT64 m = 0; m < m_pMeshHeader->NumMaterials; m++ )\r
1103             {\r
1104                 if( m_pDev9 )\r
1105                 {\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
1112                 }\r
1113                                 else if( m_pDev11 )\r
1114                 {\r
1115                     //ID3D11Resource* pRes = NULL;\r
1116                     if( m_pMaterialArray[m].pDiffuseRV11 && !IsErrorResource( m_pMaterialArray[m].pDiffuseRV11 ) )\r
1117                     {\r
1118                         //m_pMaterialArray[m].pDiffuseRV11->GetResource( &pRes );\r
1119                         //SAFE_RELEASE( pRes );\r
1120 \r
1121                         SAFE_RELEASE( m_pMaterialArray[m].pDiffuseRV11 );\r
1122                     }\r
1123                     if( m_pMaterialArray[m].pNormalRV11 && !IsErrorResource( m_pMaterialArray[m].pNormalRV11 ) )\r
1124                     {\r
1125                         //m_pMaterialArray[m].pNormalRV11->GetResource( &pRes );\r
1126                         //SAFE_RELEASE( pRes );\r
1127 \r
1128                         SAFE_RELEASE( m_pMaterialArray[m].pNormalRV11 );\r
1129                     }\r
1130                     if( m_pMaterialArray[m].pSpecularRV11 && !IsErrorResource( m_pMaterialArray[m].pSpecularRV11 ) )\r
1131                     {\r
1132                         //m_pMaterialArray[m].pSpecularRV11->GetResource( &pRes );\r
1133                         //SAFE_RELEASE( pRes );\r
1134 \r
1135                         SAFE_RELEASE( m_pMaterialArray[m].pSpecularRV11 );\r
1136                     }\r
1137                 }\r
1138             }\r
1139         }\r
1140 \r
1141         for( UINT64 i = 0; i < m_pMeshHeader->NumVertexBuffers; i++ )\r
1142         {\r
1143             if( !IsErrorResource( m_pVertexBufferArray[i].pVB9 ) )\r
1144                 SAFE_RELEASE( m_pVertexBufferArray[i].pVB9 );\r
1145         }\r
1146 \r
1147         for( UINT64 i = 0; i < m_pMeshHeader->NumIndexBuffers; i++ )\r
1148         {\r
1149             if( !IsErrorResource( m_pIndexBufferArray[i].pIB9 ) )\r
1150                 SAFE_RELEASE( m_pIndexBufferArray[i].pIB9 );\r
1151         }\r
1152     }\r
1153 \r
1154     if( m_pAdjacencyIndexBufferArray )\r
1155     {\r
1156         for( UINT64 i = 0; i < m_pMeshHeader->NumIndexBuffers; i++ )\r
1157         {\r
1158             SAFE_RELEASE( m_pAdjacencyIndexBufferArray[i].pIB11 );\r
1159         }\r
1160     }\r
1161     SAFE_DELETE_ARRAY( m_pAdjacencyIndexBufferArray );\r
1162 \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
1169 \r
1170     SAFE_DELETE_ARRAY( m_ppVertices );\r
1171     SAFE_DELETE_ARRAY( m_ppIndices );\r
1172 \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
1180 \r
1181     m_pAnimationHeader = NULL;\r
1182     m_pAnimationFrameData = NULL;\r
1183 \r
1184 }\r
1185 \r
1186 //--------------------------------------------------------------------------------------\r
1187 // transform the bind pose\r
1188 //--------------------------------------------------------------------------------------\r
1189 void CDXUTSDKMesh::TransformBindPose( D3DXMATRIX* pWorld )\r
1190 {\r
1191     TransformBindPoseFrame( 0, pWorld );\r
1192 }\r
1193 \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
1198 {\r
1199     if( m_pAnimationHeader == NULL || FTT_RELATIVE == m_pAnimationHeader->FrameTransformType )\r
1200     {\r
1201         TransformFrame( 0, pWorld, fTime );\r
1202 \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
1208         {\r
1209             D3DXMatrixInverse( &mInvBindPose, NULL, &m_pBindPoseFrameMatrices[i] );\r
1210             mFinal = mInvBindPose * m_pTransformedFrameMatrices[i];\r
1211             m_pTransformedFrameMatrices[i] = mFinal;\r
1212         }\r
1213     }\r
1214     else if( FTT_ABSOLUTE == m_pAnimationHeader->FrameTransformType )\r
1215     {\r
1216         for( UINT i = 0; i < m_pAnimationHeader->NumFrames; i++ )\r
1217             TransformFrameAbsolute( i, fTime );\r
1218     }\r
1219 }\r
1220 \r
1221 \r
1222 //--------------------------------------------------------------------------------------\r
1223 void CDXUTSDKMesh::Render( ID3D11DeviceContext* pd3dDeviceContext,\r
1224                            UINT iDiffuseSlot,\r
1225                            UINT iNormalSlot,\r
1226                            UINT iSpecularSlot )\r
1227 {\r
1228     RenderFrame( 0, false, pd3dDeviceContext, iDiffuseSlot, iNormalSlot, iSpecularSlot );\r
1229 }\r
1230 \r
1231 //--------------------------------------------------------------------------------------\r
1232 void CDXUTSDKMesh::RenderAdjacent( ID3D11DeviceContext* pd3dDeviceContext,\r
1233                                    UINT iDiffuseSlot,\r
1234                                    UINT iNormalSlot,\r
1235                                    UINT iSpecularSlot )\r
1236 {\r
1237     RenderFrame( 0, true, pd3dDeviceContext, iDiffuseSlot, iNormalSlot, iSpecularSlot );\r
1238 }\r
1239 \r
1240 \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
1248 {\r
1249     RenderFrame( 0, pd3dDevice, pEffect, hTechnique, htxDiffuse, htxNormal, htxSpecular );\r
1250 }\r
1251 \r
1252 //--------------------------------------------------------------------------------------\r
1253 D3D11_PRIMITIVE_TOPOLOGY CDXUTSDKMesh::GetPrimitiveType11( SDKMESH_PRIMITIVE_TYPE PrimType )\r
1254 {\r
1255     D3D11_PRIMITIVE_TOPOLOGY retType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;\r
1256 \r
1257     switch( PrimType )\r
1258     {\r
1259         case PT_TRIANGLE_LIST:\r
1260             retType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;\r
1261             break;\r
1262         case PT_TRIANGLE_STRIP:\r
1263             retType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;\r
1264             break;\r
1265         case PT_LINE_LIST:\r
1266             retType = D3D11_PRIMITIVE_TOPOLOGY_LINELIST;\r
1267             break;\r
1268         case PT_LINE_STRIP:\r
1269             retType = D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP;\r
1270             break;\r
1271         case PT_POINT_LIST:\r
1272             retType = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;\r
1273             break;\r
1274         case PT_TRIANGLE_LIST_ADJ:\r
1275             retType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST_ADJ;\r
1276             break;\r
1277         case PT_TRIANGLE_STRIP_ADJ:\r
1278             retType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP_ADJ;\r
1279             break;\r
1280         case PT_LINE_LIST_ADJ:\r
1281             retType = D3D11_PRIMITIVE_TOPOLOGY_LINELIST_ADJ;\r
1282             break;\r
1283         case PT_LINE_STRIP_ADJ:\r
1284             retType = D3D11_PRIMITIVE_TOPOLOGY_LINESTRIP_ADJ;\r
1285             break;\r
1286     };\r
1287 \r
1288     return retType;\r
1289 }\r
1290 \r
1291 //--------------------------------------------------------------------------------------\r
1292 DXGI_FORMAT CDXUTSDKMesh::GetIBFormat11( UINT iMesh )\r
1293 {\r
1294     switch( m_pIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].IndexType )\r
1295     {\r
1296         case IT_16BIT:\r
1297             return DXGI_FORMAT_R16_UINT;\r
1298         case IT_32BIT:\r
1299             return DXGI_FORMAT_R32_UINT;\r
1300     };\r
1301     return DXGI_FORMAT_R16_UINT;\r
1302 }\r
1303 \r
1304 //--------------------------------------------------------------------------------------\r
1305 ID3D11Buffer* CDXUTSDKMesh::GetVB11( UINT iMesh, UINT iVB )\r
1306 {\r
1307     return m_pVertexBufferArray[ m_pMeshArray[ iMesh ].VertexBuffers[iVB] ].pVB11;\r
1308 }\r
1309 \r
1310 //--------------------------------------------------------------------------------------\r
1311 ID3D11Buffer* CDXUTSDKMesh::GetIB11( UINT iMesh )\r
1312 {\r
1313     return m_pIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].pIB11;\r
1314 }\r
1315 SDKMESH_INDEX_TYPE CDXUTSDKMesh::GetIndexType( UINT iMesh ) \r
1316 {\r
1317     return ( SDKMESH_INDEX_TYPE ) m_pIndexBufferArray[m_pMeshArray[ iMesh ].IndexBuffer].IndexType;\r
1318 }\r
1319 //--------------------------------------------------------------------------------------\r
1320 ID3D11Buffer* CDXUTSDKMesh::GetAdjIB11( UINT iMesh )\r
1321 {\r
1322     return m_pAdjacencyIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].pIB11;\r
1323 }\r
1324 \r
1325 //--------------------------------------------------------------------------------------\r
1326 D3DPRIMITIVETYPE CDXUTSDKMesh::GetPrimitiveType9( SDKMESH_PRIMITIVE_TYPE PrimType )\r
1327 {\r
1328     D3DPRIMITIVETYPE retType = D3DPT_TRIANGLELIST;\r
1329 \r
1330     switch( PrimType )\r
1331     {\r
1332         case PT_TRIANGLE_LIST:\r
1333             retType = D3DPT_TRIANGLELIST;\r
1334             break;\r
1335         case PT_TRIANGLE_STRIP:\r
1336             retType = D3DPT_TRIANGLESTRIP;\r
1337             break;\r
1338         case PT_LINE_LIST:\r
1339             retType = D3DPT_LINELIST;\r
1340             break;\r
1341         case PT_LINE_STRIP:\r
1342             retType = D3DPT_LINESTRIP;\r
1343             break;\r
1344         case PT_POINT_LIST:\r
1345             retType = D3DPT_POINTLIST;\r
1346             break;\r
1347     };\r
1348 \r
1349     return retType;\r
1350 }\r
1351 \r
1352 //--------------------------------------------------------------------------------------\r
1353 D3DFORMAT CDXUTSDKMesh::GetIBFormat9( UINT iMesh )\r
1354 {\r
1355     switch( m_pIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].IndexType )\r
1356     {\r
1357         case IT_16BIT:\r
1358             return D3DFMT_INDEX16;\r
1359         case IT_32BIT:\r
1360             return D3DFMT_INDEX32;\r
1361     };\r
1362     return D3DFMT_INDEX16;\r
1363 }\r
1364 \r
1365 //--------------------------------------------------------------------------------------\r
1366 IDirect3DVertexBuffer9* CDXUTSDKMesh::GetVB9( UINT iMesh, UINT iVB )\r
1367 {\r
1368     return m_pVertexBufferArray[ m_pMeshArray[ iMesh ].VertexBuffers[iVB] ].pVB9;\r
1369 }\r
1370 \r
1371 //--------------------------------------------------------------------------------------\r
1372 IDirect3DIndexBuffer9* CDXUTSDKMesh::GetIB9( UINT iMesh )\r
1373 {\r
1374     return m_pIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].pIB9;\r
1375 }\r
1376 \r
1377 //--------------------------------------------------------------------------------------\r
1378 char* CDXUTSDKMesh::GetMeshPathA()\r
1379 {\r
1380     return m_strPath;\r
1381 }\r
1382 \r
1383 //--------------------------------------------------------------------------------------\r
1384 WCHAR* CDXUTSDKMesh::GetMeshPathW()\r
1385 {\r
1386     return m_strPathW;\r
1387 }\r
1388 \r
1389 //--------------------------------------------------------------------------------------\r
1390 UINT CDXUTSDKMesh::GetNumMeshes()\r
1391 {\r
1392     if( !m_pMeshHeader )\r
1393         return 0;\r
1394     return m_pMeshHeader->NumMeshes;\r
1395 }\r
1396 \r
1397 //--------------------------------------------------------------------------------------\r
1398 UINT CDXUTSDKMesh::GetNumMaterials()\r
1399 {\r
1400     if( !m_pMeshHeader )\r
1401         return 0;\r
1402     return m_pMeshHeader->NumMaterials;\r
1403 }\r
1404 \r
1405 //--------------------------------------------------------------------------------------\r
1406 UINT CDXUTSDKMesh::GetNumVBs()\r
1407 {\r
1408     if( !m_pMeshHeader )\r
1409         return 0;\r
1410     return m_pMeshHeader->NumVertexBuffers;\r
1411 }\r
1412 \r
1413 //--------------------------------------------------------------------------------------\r
1414 UINT CDXUTSDKMesh::GetNumIBs()\r
1415 {\r
1416     if( !m_pMeshHeader )\r
1417         return 0;\r
1418     return m_pMeshHeader->NumIndexBuffers;\r
1419 }\r
1420 \r
1421 //--------------------------------------------------------------------------------------\r
1422 ID3D11Buffer* CDXUTSDKMesh::GetVB11At( UINT iVB )\r
1423 {\r
1424     return m_pVertexBufferArray[ iVB ].pVB11;\r
1425 }\r
1426 \r
1427 //--------------------------------------------------------------------------------------\r
1428 ID3D11Buffer* CDXUTSDKMesh::GetIB11At( UINT iIB )\r
1429 {\r
1430     return m_pIndexBufferArray[ iIB ].pIB11;\r
1431 }\r
1432 \r
1433 //--------------------------------------------------------------------------------------\r
1434 IDirect3DVertexBuffer9* CDXUTSDKMesh::GetVB9At( UINT iVB )\r
1435 {\r
1436     return m_pVertexBufferArray[ iVB ].pVB9;\r
1437 }\r
1438 \r
1439 //--------------------------------------------------------------------------------------\r
1440 IDirect3DIndexBuffer9* CDXUTSDKMesh::GetIB9At( UINT iIB )\r
1441 {\r
1442     return m_pIndexBufferArray[ iIB ].pIB9;\r
1443 }\r
1444 \r
1445 //--------------------------------------------------------------------------------------\r
1446 BYTE* CDXUTSDKMesh::GetRawVerticesAt( UINT iVB )\r
1447 {\r
1448     return m_ppVertices[iVB];\r
1449 }\r
1450 \r
1451 //--------------------------------------------------------------------------------------\r
1452 BYTE* CDXUTSDKMesh::GetRawIndicesAt( UINT iIB )\r
1453 {\r
1454     return m_ppIndices[iIB];\r
1455 }\r
1456 \r
1457 //--------------------------------------------------------------------------------------\r
1458 SDKMESH_MATERIAL* CDXUTSDKMesh::GetMaterial( UINT iMaterial )\r
1459 {\r
1460     return &m_pMaterialArray[ iMaterial ];\r
1461 }\r
1462 \r
1463 //--------------------------------------------------------------------------------------\r
1464 SDKMESH_MESH* CDXUTSDKMesh::GetMesh( UINT iMesh )\r
1465 {\r
1466     return &m_pMeshArray[ iMesh ];\r
1467 }\r
1468 \r
1469 //--------------------------------------------------------------------------------------\r
1470 UINT CDXUTSDKMesh::GetNumSubsets( UINT iMesh )\r
1471 {\r
1472     return m_pMeshArray[ iMesh ].NumSubsets;\r
1473 }\r
1474 \r
1475 //--------------------------------------------------------------------------------------\r
1476 SDKMESH_SUBSET* CDXUTSDKMesh::GetSubset( UINT iMesh, UINT iSubset )\r
1477 {\r
1478     return &m_pSubsetArray[ m_pMeshArray[ iMesh ].pSubsets[iSubset] ];\r
1479 }\r
1480 \r
1481 //--------------------------------------------------------------------------------------\r
1482 UINT CDXUTSDKMesh::GetVertexStride( UINT iMesh, UINT iVB )\r
1483 {\r
1484     return ( UINT )m_pVertexBufferArray[ m_pMeshArray[ iMesh ].VertexBuffers[iVB] ].StrideBytes;\r
1485 }\r
1486 \r
1487 //--------------------------------------------------------------------------------------\r
1488 UINT CDXUTSDKMesh::GetNumFrames()\r
1489 {\r
1490     return m_pMeshHeader->NumFrames;\r
1491 }\r
1492 \r
1493 //--------------------------------------------------------------------------------------\r
1494 SDKMESH_FRAME* CDXUTSDKMesh::GetFrame( UINT iFrame )\r
1495 {\r
1496     assert( iFrame < m_pMeshHeader->NumFrames );\r
1497     return &m_pFrameArray[ iFrame ];\r
1498 }\r
1499 \r
1500 //--------------------------------------------------------------------------------------\r
1501 SDKMESH_FRAME* CDXUTSDKMesh::FindFrame( char* pszName )\r
1502 {\r
1503     for( UINT i = 0; i < m_pMeshHeader->NumFrames; i++ )\r
1504     {\r
1505         if( _stricmp( m_pFrameArray[i].Name, pszName ) == 0 )\r
1506         {\r
1507             return &m_pFrameArray[i];\r
1508         }\r
1509     }\r
1510     return NULL;\r
1511 }\r
1512 \r
1513 //--------------------------------------------------------------------------------------\r
1514 UINT64 CDXUTSDKMesh::GetNumVertices( UINT iMesh, UINT iVB )\r
1515 {\r
1516     return m_pVertexBufferArray[ m_pMeshArray[ iMesh ].VertexBuffers[iVB] ].NumVertices;\r
1517 }\r
1518 \r
1519 //--------------------------------------------------------------------------------------\r
1520 UINT64 CDXUTSDKMesh::GetNumIndices( UINT iMesh )\r
1521 {\r
1522     return m_pIndexBufferArray[ m_pMeshArray[ iMesh ].IndexBuffer ].NumIndices;\r
1523 }\r
1524 \r
1525 //--------------------------------------------------------------------------------------\r
1526 D3DXVECTOR3 CDXUTSDKMesh::GetMeshBBoxCenter( UINT iMesh )\r
1527 {\r
1528     return m_pMeshArray[iMesh].BoundingBoxCenter;\r
1529 }\r
1530 \r
1531 //--------------------------------------------------------------------------------------\r
1532 D3DXVECTOR3 CDXUTSDKMesh::GetMeshBBoxExtents( UINT iMesh )\r
1533 {\r
1534     return m_pMeshArray[iMesh].BoundingBoxExtents;\r
1535 }\r
1536 \r
1537 //--------------------------------------------------------------------------------------\r
1538 UINT CDXUTSDKMesh::GetOutstandingResources()\r
1539 {\r
1540     UINT outstandingResources = 0;\r
1541     if( !m_pMeshHeader )\r
1542         return 1;\r
1543 \r
1544     outstandingResources += GetOutstandingBufferResources();\r
1545 \r
1546         if( m_pDev11 )\r
1547         {\r
1548                 for( UINT i = 0; i < m_pMeshHeader->NumMaterials; i++ )\r
1549         {\r
1550             if( m_pMaterialArray[i].DiffuseTexture[0] != 0 )\r
1551             {\r
1552                 if( !m_pMaterialArray[i].pDiffuseRV11 && !IsErrorResource( m_pMaterialArray[i].pDiffuseRV11 ) )\r
1553                     outstandingResources ++;\r
1554             }\r
1555 \r
1556             if( m_pMaterialArray[i].NormalTexture[0] != 0 )\r
1557             {\r
1558                 if( !m_pMaterialArray[i].pNormalRV11 && !IsErrorResource( m_pMaterialArray[i].pNormalRV11 ) )\r
1559                     outstandingResources ++;\r
1560             }\r
1561 \r
1562             if( m_pMaterialArray[i].SpecularTexture[0] != 0 )\r
1563             {\r
1564                 if( !m_pMaterialArray[i].pSpecularRV11 && !IsErrorResource( m_pMaterialArray[i].pSpecularRV11 ) )\r
1565                     outstandingResources ++;\r
1566             }\r
1567         }\r
1568         }\r
1569     else\r
1570     {\r
1571         for( UINT i = 0; i < m_pMeshHeader->NumMaterials; i++ )\r
1572         {\r
1573             if( m_pMaterialArray[i].DiffuseTexture[0] != 0 )\r
1574             {\r
1575                 if( !m_pMaterialArray[i].pDiffuseTexture9 && !IsErrorResource( m_pMaterialArray[i].pDiffuseTexture9 ) )\r
1576                     outstandingResources ++;\r
1577             }\r
1578 \r
1579             if( m_pMaterialArray[i].NormalTexture[0] != 0 )\r
1580             {\r
1581                 if( !m_pMaterialArray[i].pNormalTexture9 && !IsErrorResource( m_pMaterialArray[i].pNormalTexture9 ) )\r
1582                     outstandingResources ++;\r
1583             }\r
1584 \r
1585             if( m_pMaterialArray[i].SpecularTexture[0] != 0 )\r
1586             {\r
1587                 if( !m_pMaterialArray[i].pSpecularTexture9 &&\r
1588                     !IsErrorResource( m_pMaterialArray[i].pSpecularTexture9 ) )\r
1589                     outstandingResources ++;\r
1590             }\r
1591         }\r
1592     }\r
1593 \r
1594     return outstandingResources;\r
1595 }\r
1596 \r
1597 //--------------------------------------------------------------------------------------\r
1598 UINT CDXUTSDKMesh::GetOutstandingBufferResources()\r
1599 {\r
1600     UINT outstandingResources = 0;\r
1601     if( !m_pMeshHeader )\r
1602         return 1;\r
1603 \r
1604     for( UINT i = 0; i < m_pMeshHeader->NumVertexBuffers; i++ )\r
1605     {\r
1606         if( !m_pVertexBufferArray[i].pVB9 && !IsErrorResource( m_pVertexBufferArray[i].pVB9 ) )\r
1607             outstandingResources ++;\r
1608     }\r
1609 \r
1610     for( UINT i = 0; i < m_pMeshHeader->NumIndexBuffers; i++ )\r
1611     {\r
1612         if( !m_pIndexBufferArray[i].pIB9 && !IsErrorResource( m_pIndexBufferArray[i].pIB9 ) )\r
1613             outstandingResources ++;\r
1614     }\r
1615 \r
1616     return outstandingResources;\r
1617 }\r
1618 \r
1619 //--------------------------------------------------------------------------------------\r
1620 bool CDXUTSDKMesh::CheckLoadDone()\r
1621 {\r
1622     if( 0 == GetOutstandingResources() )\r
1623     {\r
1624         m_bLoading = false;\r
1625         return true;\r
1626     }\r
1627 \r
1628     return false;\r
1629 }\r
1630 \r
1631 //--------------------------------------------------------------------------------------\r
1632 bool CDXUTSDKMesh::IsLoaded()\r
1633 {\r
1634     if( m_pStaticMeshData && !m_bLoading )\r
1635     {\r
1636         return true;\r
1637     }\r
1638 \r
1639     return false;\r
1640 }\r
1641 \r
1642 //--------------------------------------------------------------------------------------\r
1643 bool CDXUTSDKMesh::IsLoading()\r
1644 {\r
1645     return m_bLoading;\r
1646 }\r
1647 \r
1648 //--------------------------------------------------------------------------------------\r
1649 void CDXUTSDKMesh::SetLoading( bool bLoading )\r
1650 {\r
1651     m_bLoading = bLoading;\r
1652 }\r
1653 \r
1654 //--------------------------------------------------------------------------------------\r
1655 BOOL CDXUTSDKMesh::HadLoadingError()\r
1656 {\r
1657     if( m_pMeshHeader )\r
1658     {\r
1659         for( UINT i = 0; i < m_pMeshHeader->NumVertexBuffers; i++ )\r
1660         {\r
1661             if( IsErrorResource( m_pVertexBufferArray[i].pVB9 ) )\r
1662                 return TRUE;\r
1663         }\r
1664 \r
1665         for( UINT i = 0; i < m_pMeshHeader->NumIndexBuffers; i++ )\r
1666         {\r
1667             if( IsErrorResource( m_pIndexBufferArray[i].pIB9 ) )\r
1668                 return TRUE;\r
1669         }\r
1670     }\r
1671 \r
1672     return FALSE;\r
1673 }\r
1674 \r
1675 //--------------------------------------------------------------------------------------\r
1676 UINT CDXUTSDKMesh::GetNumInfluences( UINT iMesh )\r
1677 {\r
1678     return m_pMeshArray[iMesh].NumFrameInfluences;\r
1679 }\r
1680 \r
1681 //--------------------------------------------------------------------------------------\r
1682 const D3DXMATRIX* CDXUTSDKMesh::GetMeshInfluenceMatrix( UINT iMesh, UINT iInfluence )\r
1683 {\r
1684     UINT iFrame = m_pMeshArray[iMesh].pFrameInfluences[ iInfluence ];\r
1685     return &m_pTransformedFrameMatrices[iFrame];\r
1686 }\r
1687 \r
1688 const D3DXMATRIX* CDXUTSDKMesh::GetWorldMatrix( UINT iFrameIndex )\r
1689 {\r
1690     return &m_pWorldPoseFrameMatrices[iFrameIndex];\r
1691 }\r
1692 \r
1693 const D3DXMATRIX* CDXUTSDKMesh::GetInfluenceMatrix( UINT iFrameIndex )\r
1694 {\r
1695     return &m_pTransformedFrameMatrices[iFrameIndex];\r
1696 }\r
1697 \r
1698 //--------------------------------------------------------------------------------------\r
1699 UINT CDXUTSDKMesh::GetAnimationKeyFromTime( double fTime )\r
1700 {\r
1701     if( m_pAnimationHeader == NULL )\r
1702     {\r
1703         return 0;\r
1704     }\r
1705 \r
1706     UINT iTick = ( UINT )( m_pAnimationHeader->AnimationFPS * fTime );\r
1707 \r
1708     iTick = iTick % ( m_pAnimationHeader->NumAnimationKeys - 1 );\r
1709     iTick ++;\r
1710 \r
1711     return iTick;\r
1712 }\r
1713 \r
1714 bool CDXUTSDKMesh::GetAnimationProperties( UINT* pNumKeys, FLOAT* pFrameTime )\r
1715 {\r
1716     if( m_pAnimationHeader == NULL )\r
1717     {\r
1718         return false;\r
1719     }\r
1720 \r
1721     *pNumKeys = m_pAnimationHeader->NumAnimationKeys;\r
1722     *pFrameTime = 1.0f / (FLOAT)m_pAnimationHeader->AnimationFPS;\r
1723 \r
1724     return true;\r
1725 }\r
1726 \r
1727 \r
1728 //-------------------------------------------------------------------------------------\r
1729 // CDXUTXFileMesh implementation.\r
1730 //-------------------------------------------------------------------------------------\r
1731 \r
1732 //-----------------------------------------------------------------------------\r
1733 CDXUTXFileMesh::CDXUTXFileMesh( LPCWSTR strName )\r
1734 {\r
1735     wcscpy_s( m_strName, 512, strName );\r
1736     m_pMesh = NULL;\r
1737     m_pMaterials = NULL;\r
1738     m_pTextures = NULL;\r
1739     m_bUseMaterials = TRUE;\r
1740     m_pVB = NULL;\r
1741     m_pIB = NULL;\r
1742     m_pDecl = NULL;\r
1743     m_strMaterials = NULL;\r
1744     m_dwNumMaterials = 0;\r
1745     m_dwNumVertices = 0;\r
1746     m_dwNumFaces = 0;\r
1747     m_dwBytesPerVertex = 0;\r
1748 }\r
1749 \r
1750 \r
1751 \r
1752 \r
1753 //-----------------------------------------------------------------------------\r
1754 CDXUTXFileMesh::~CDXUTXFileMesh()\r
1755 {\r
1756     Destroy();\r
1757 }\r
1758 \r
1759 \r
1760 \r
1761 \r
1762 //-----------------------------------------------------------------------------\r
1763 HRESULT CDXUTXFileMesh::Create( LPDIRECT3DDEVICE9 pd3dDevice, LPCWSTR strFilename )\r
1764 {\r
1765     WCHAR strPath[MAX_PATH];\r
1766     LPD3DXBUFFER pAdjacencyBuffer = NULL;\r
1767     LPD3DXBUFFER pMtrlBuffer = NULL;\r
1768     HRESULT hr;\r
1769 \r
1770     // Cleanup previous mesh if any\r
1771     Destroy();\r
1772 \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
1775 \r
1776     // Load the mesh\r
1777     if( FAILED( hr = D3DXLoadMeshFromX( strPath, D3DXMESH_MANAGED, pd3dDevice,\r
1778                                         &pAdjacencyBuffer, &pMtrlBuffer, NULL,\r
1779                                         &m_dwNumMaterials, &m_pMesh ) ) )\r
1780     {\r
1781         return hr;\r
1782     }\r
1783 \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
1788     {\r
1789         SAFE_RELEASE( pAdjacencyBuffer );\r
1790         SAFE_RELEASE( pMtrlBuffer );\r
1791         return hr;\r
1792     }\r
1793 \r
1794     // Set strPath to the path of the mesh file\r
1795     WCHAR* pLastBSlash = wcsrchr( strPath, L'\\' );\r
1796     if( pLastBSlash )\r
1797         *( pLastBSlash + 1 ) = L'\0';\r
1798     else\r
1799         *strPath = L'\0';\r
1800 \r
1801     D3DXMATERIAL* d3dxMtrls = ( D3DXMATERIAL* )pMtrlBuffer->GetBufferPointer();\r
1802     hr = CreateMaterials( strPath, pd3dDevice, d3dxMtrls, m_dwNumMaterials );\r
1803 \r
1804     SAFE_RELEASE( pAdjacencyBuffer );\r
1805     SAFE_RELEASE( pMtrlBuffer );\r
1806 \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
1816 \r
1817     return hr;\r
1818 }\r
1819 \r
1820 \r
1821 //-----------------------------------------------------------------------------\r
1822 HRESULT CDXUTXFileMesh::Create( LPDIRECT3DDEVICE9 pd3dDevice,\r
1823                                 LPD3DXFILEDATA pFileData )\r
1824 {\r
1825     LPD3DXBUFFER pMtrlBuffer = NULL;\r
1826     LPD3DXBUFFER pAdjacencyBuffer = NULL;\r
1827     HRESULT hr;\r
1828 \r
1829     // Cleanup previous mesh if any\r
1830     Destroy();\r
1831 \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
1836     {\r
1837         return hr;\r
1838     }\r
1839 \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
1844     {\r
1845         SAFE_RELEASE( pAdjacencyBuffer );\r
1846         SAFE_RELEASE( pMtrlBuffer );\r
1847         return hr;\r
1848     }\r
1849 \r
1850     D3DXMATERIAL* d3dxMtrls = ( D3DXMATERIAL* )pMtrlBuffer->GetBufferPointer();\r
1851     hr = CreateMaterials( L"", pd3dDevice, d3dxMtrls, m_dwNumMaterials );\r
1852 \r
1853     SAFE_RELEASE( pAdjacencyBuffer );\r
1854     SAFE_RELEASE( pMtrlBuffer );\r
1855 \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
1865 \r
1866     return hr;\r
1867 }\r
1868 \r
1869 \r
1870 //-----------------------------------------------------------------------------\r
1871 HRESULT CDXUTXFileMesh::Create( LPDIRECT3DDEVICE9 pd3dDevice, ID3DXMesh* pInMesh,\r
1872                                 D3DXMATERIAL* pd3dxMaterials, DWORD dwMaterials )\r
1873 {\r
1874     // Cleanup previous mesh if any\r
1875     Destroy();\r
1876 \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
1883 \r
1884     D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];\r
1885     pInMesh->GetDeclaration( decl );\r
1886 \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
1891 \r
1892     ID3DXMesh* pTempMesh = NULL;\r
1893     if( FAILED( pInMesh->Optimize( dwOptions, rgdwAdjacency, NULL, NULL, NULL, &pTempMesh ) ) )\r
1894     {\r
1895         SAFE_DELETE_ARRAY( rgdwAdjacency );\r
1896         return E_FAIL;\r
1897     }\r
1898 \r
1899     SAFE_DELETE_ARRAY( rgdwAdjacency );\r
1900     SAFE_RELEASE( m_pMesh );\r
1901     m_pMesh = pTempMesh;\r
1902 \r
1903     HRESULT hr;\r
1904     hr = CreateMaterials( L"", pd3dDevice, pd3dxMaterials, dwMaterials );\r
1905 \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
1914 \r
1915     return hr;\r
1916 }\r
1917 \r
1918 \r
1919 //-----------------------------------------------------------------------------\r
1920 HRESULT CDXUTXFileMesh::CreateMaterials( LPCWSTR strPath, IDirect3DDevice9* pd3dDevice, D3DXMATERIAL* d3dxMtrls,\r
1921                                          DWORD dwNumMaterials )\r
1922 {\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
1927     {\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
1938 \r
1939         // Copy each material and create its texture\r
1940         for( DWORD i = 0; i < m_dwNumMaterials; i++ )\r
1941         {\r
1942             // Copy the material\r
1943             m_pMaterials[i] = d3dxMtrls[i].MatD3D;\r
1944             m_pTextures[i] = NULL;\r
1945 \r
1946             // Create a texture\r
1947             if( d3dxMtrls[i].pTextureFilename )\r
1948             {\r
1949                 strcpy_s( m_strMaterials[i], MAX_PATH, d3dxMtrls[i].pTextureFilename );\r
1950 \r
1951                 WCHAR strTexture[MAX_PATH];\r
1952                 WCHAR strTextureTemp[MAX_PATH];\r
1953                 D3DXIMAGE_INFO ImgInfo;\r
1954 \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
1958 \r
1959                 wcscpy_s( strTexture, MAX_PATH, strPath );\r
1960                 wcscat_s( strTexture, MAX_PATH, strTextureTemp );\r
1961 \r
1962                 // Inspect the texture file to determine the texture type.\r
1963                 if( FAILED( D3DXGetImageInfoFromFile( strTexture, &ImgInfo ) ) )\r
1964                 {\r
1965                     // Search the media folder\r
1966                     if( FAILED( DXUTFindDXSDKMediaFileCch( strTexture, MAX_PATH, strTextureTemp ) ) )\r
1967                         continue;  // Can't find. Skip.\r
1968 \r
1969                     D3DXGetImageInfoFromFile( strTexture, &ImgInfo );\r
1970                 }\r
1971 \r
1972                 // Call the appropriate loader according to the texture type.\r
1973                 switch( ImgInfo.ResourceType )\r
1974                 {\r
1975                     case D3DRTYPE_TEXTURE:\r
1976                     {\r
1977                         IDirect3DTexture9* pTex;\r
1978                         if( SUCCEEDED( D3DXCreateTextureFromFile( pd3dDevice, strTexture, &pTex ) ) )\r
1979                         {\r
1980                             // Obtain the base texture interface\r
1981                             pTex->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&m_pTextures[i] );\r
1982                             // Release the specialized instance\r
1983                             pTex->Release();\r
1984                         }\r
1985                         break;\r
1986                     }\r
1987                     case D3DRTYPE_CUBETEXTURE:\r
1988                     {\r
1989                         IDirect3DCubeTexture9* pTex;\r
1990                         if( SUCCEEDED( D3DXCreateCubeTextureFromFile( pd3dDevice, strTexture, &pTex ) ) )\r
1991                         {\r
1992                             // Obtain the base texture interface\r
1993                             pTex->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&m_pTextures[i] );\r
1994                             // Release the specialized instance\r
1995                             pTex->Release();\r
1996                         }\r
1997                         break;\r
1998                     }\r
1999                     case D3DRTYPE_VOLUMETEXTURE:\r
2000                     {\r
2001                         IDirect3DVolumeTexture9* pTex;\r
2002                         if( SUCCEEDED( D3DXCreateVolumeTextureFromFile( pd3dDevice, strTexture, &pTex ) ) )\r
2003                         {\r
2004                             // Obtain the base texture interface\r
2005                             pTex->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&m_pTextures[i] );\r
2006                             // Release the specialized instance\r
2007                             pTex->Release();\r
2008                         }\r
2009                         break;\r
2010                     }\r
2011                 }\r
2012             }\r
2013         }\r
2014     }\r
2015     return S_OK;\r
2016 }\r
2017 \r
2018 \r
2019 //-----------------------------------------------------------------------------\r
2020 HRESULT CDXUTXFileMesh::SetFVF( LPDIRECT3DDEVICE9 pd3dDevice, DWORD dwFVF )\r
2021 {\r
2022     LPD3DXMESH pTempMesh = NULL;\r
2023 \r
2024     if( m_pMesh )\r
2025     {\r
2026         if( FAILED( m_pMesh->CloneMeshFVF( m_pMesh->GetOptions(), dwFVF,\r
2027                                            pd3dDevice, &pTempMesh ) ) )\r
2028         {\r
2029             SAFE_RELEASE( pTempMesh );\r
2030             return E_FAIL;\r
2031         }\r
2032 \r
2033         DWORD dwOldFVF = 0;\r
2034         dwOldFVF = m_pMesh->GetFVF();\r
2035         SAFE_RELEASE( m_pMesh );\r
2036         m_pMesh = pTempMesh;\r
2037 \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
2041         {\r
2042             D3DXComputeNormals( m_pMesh, NULL );\r
2043         }\r
2044     }\r
2045 \r
2046     return S_OK;\r
2047 }\r
2048 \r
2049 \r
2050 \r
2051 \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
2058 {\r
2059     LPD3DXMESH pTempMesh = NULL;\r
2060 \r
2061     if( m_pMesh )\r
2062     {\r
2063         if( FAILED( m_pMesh->CloneMesh( m_pMesh->GetOptions(), pDecl,\r
2064                                         pd3dDevice, &pTempMesh ) ) )\r
2065         {\r
2066             SAFE_RELEASE( pTempMesh );\r
2067             return E_FAIL;\r
2068         }\r
2069     }\r
2070 \r
2071 \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
2077     {\r
2078         for( UINT index = 0; index < D3DXGetDeclLength( aOldDecl ); ++index )\r
2079         {\r
2080             if( aOldDecl[index].Usage == D3DDECLUSAGE_NORMAL )\r
2081             {\r
2082                 bHadNormal = true;\r
2083             }\r
2084             if( aOldDecl[index].Usage == D3DDECLUSAGE_TANGENT )\r
2085             {\r
2086                 bHadTangent = true;\r
2087             }\r
2088         }\r
2089     }\r
2090 \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
2096     {\r
2097         for( UINT index = 0; index < D3DXGetDeclLength( aNewDecl ); ++index )\r
2098         {\r
2099             if( aNewDecl[index].Usage == D3DDECLUSAGE_NORMAL )\r
2100             {\r
2101                 bHaveNormalNow = true;\r
2102             }\r
2103             if( aNewDecl[index].Usage == D3DDECLUSAGE_TANGENT )\r
2104             {\r
2105                 bHaveTangentNow = true;\r
2106             }\r
2107         }\r
2108     }\r
2109 \r
2110     SAFE_RELEASE( m_pMesh );\r
2111 \r
2112     if( pTempMesh )\r
2113     {\r
2114         m_pMesh = pTempMesh;\r
2115 \r
2116         if( !bHadNormal && bHaveNormalNow && bAutoComputeNormals )\r
2117         {\r
2118             // Compute normals in case the meshes have them\r
2119             D3DXComputeNormals( m_pMesh, NULL );\r
2120         }\r
2121 \r
2122         if( bHaveNormalNow && !bHadTangent && bHaveTangentNow && bAutoComputeTangents )\r
2123         {\r
2124             ID3DXMesh* pNewMesh;\r
2125             HRESULT hr;\r
2126 \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
2132 \r
2133             float fPartialEdgeThreshold;\r
2134             float fSingularPointThreshold;\r
2135             float fNormalEdgeThreshold;\r
2136             if( bSplitVertexForOptimalTangents )\r
2137             {\r
2138                 fPartialEdgeThreshold = 0.01f;\r
2139                 fSingularPointThreshold = 0.25f;\r
2140                 fNormalEdgeThreshold = 0.01f;\r
2141             }\r
2142             else\r
2143             {\r
2144                 fPartialEdgeThreshold = -1.01f;\r
2145                 fSingularPointThreshold = 0.01f;\r
2146                 fNormalEdgeThreshold = -1.01f;\r
2147             }\r
2148 \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
2153                                             D3DX_DEFAULT, 0,\r
2154                                             D3DDECLUSAGE_NORMAL, 0,\r
2155                                             0, rgdwAdjacency,\r
2156                                             fPartialEdgeThreshold, fSingularPointThreshold, fNormalEdgeThreshold,\r
2157                                             &pNewMesh, NULL );\r
2158 \r
2159             SAFE_DELETE_ARRAY( rgdwAdjacency );\r
2160             if( FAILED( hr ) )\r
2161                 return hr;\r
2162 \r
2163             SAFE_RELEASE( m_pMesh );\r
2164             m_pMesh = pNewMesh;\r
2165         }\r
2166     }\r
2167 \r
2168     return S_OK;\r
2169 }\r
2170 \r
2171 \r
2172 \r
2173 \r
2174 //-----------------------------------------------------------------------------\r
2175 HRESULT CDXUTXFileMesh::RestoreDeviceObjects( LPDIRECT3DDEVICE9 pd3dDevice )\r
2176 {\r
2177     return S_OK;\r
2178 }\r
2179 \r
2180 \r
2181 \r
2182 \r
2183 //-----------------------------------------------------------------------------\r
2184 HRESULT CDXUTXFileMesh::InvalidateDeviceObjects()\r
2185 {\r
2186     SAFE_RELEASE( m_pIB );\r
2187     SAFE_RELEASE( m_pVB );\r
2188     SAFE_RELEASE( m_pDecl );\r
2189 \r
2190     return S_OK;\r
2191 }\r
2192 \r
2193 \r
2194 \r
2195 \r
2196 //-----------------------------------------------------------------------------\r
2197 HRESULT CDXUTXFileMesh::Destroy()\r
2198 {\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
2205 \r
2206     SAFE_RELEASE( m_pMesh );\r
2207 \r
2208     m_dwNumMaterials = 0L;\r
2209 \r
2210     return S_OK;\r
2211 }\r
2212 \r
2213 \r
2214 \r
2215 \r
2216 //-----------------------------------------------------------------------------\r
2217 HRESULT CDXUTXFileMesh::Render( LPDIRECT3DDEVICE9 pd3dDevice, bool bDrawOpaqueSubsets,\r
2218                                 bool bDrawAlphaSubsets )\r
2219 {\r
2220     if( NULL == m_pMesh )\r
2221         return E_FAIL;\r
2222 \r
2223     // Frist, draw the subsets without alpha\r
2224     if( bDrawOpaqueSubsets )\r
2225     {\r
2226         for( DWORD i = 0; i < m_dwNumMaterials; i++ )\r
2227         {\r
2228             if( m_bUseMaterials )\r
2229             {\r
2230                 if( m_pMaterials[i].Diffuse.a < 1.0f )\r
2231                     continue;\r
2232                 pd3dDevice->SetMaterial( &m_pMaterials[i] );\r
2233                 pd3dDevice->SetTexture( 0, m_pTextures[i] );\r
2234             }\r
2235             m_pMesh->DrawSubset( i );\r
2236         }\r
2237     }\r
2238 \r
2239     // Then, draw the subsets with alpha\r
2240     if( bDrawAlphaSubsets && m_bUseMaterials )\r
2241     {\r
2242         for( DWORD i = 0; i < m_dwNumMaterials; i++ )\r
2243         {\r
2244             if( m_pMaterials[i].Diffuse.a == 1.0f )\r
2245                 continue;\r
2246 \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
2251         }\r
2252     }\r
2253 \r
2254     return S_OK;\r
2255 }\r
2256 \r
2257 \r
2258 \r
2259 \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
2270 {\r
2271     if( NULL == m_pMesh )\r
2272         return E_FAIL;\r
2273 \r
2274     UINT cPasses;\r
2275     // Frist, draw the subsets without alpha\r
2276     if( bDrawOpaqueSubsets )\r
2277     {\r
2278         pEffect->Begin( &cPasses, 0 );\r
2279         for( UINT p = 0; p < cPasses; ++p )\r
2280         {\r
2281             pEffect->BeginPass( p );\r
2282             for( DWORD i = 0; i < m_dwNumMaterials; i++ )\r
2283             {\r
2284                 if( m_bUseMaterials )\r
2285                 {\r
2286                     if( m_pMaterials[i].Diffuse.a < 1.0f )\r
2287                         continue;\r
2288                     if( hTexture )\r
2289                         pEffect->SetTexture( hTexture, m_pTextures[i] );\r
2290                     // D3DCOLORVALUE and D3DXVECTOR4 are data-wise identical.\r
2291                     // No conversion is needed.\r
2292                     if( hDiffuse )\r
2293                         pEffect->SetVector( hDiffuse, ( D3DXVECTOR4* )&m_pMaterials[i].Diffuse );\r
2294                     if( hAmbient )\r
2295                         pEffect->SetVector( hAmbient, ( D3DXVECTOR4* )&m_pMaterials[i].Ambient );\r
2296                     if( hSpecular )\r
2297                         pEffect->SetVector( hSpecular, ( D3DXVECTOR4* )&m_pMaterials[i].Specular );\r
2298                     if( hEmissive )\r
2299                         pEffect->SetVector( hEmissive, ( D3DXVECTOR4* )&m_pMaterials[i].Emissive );\r
2300                     if( hPower )\r
2301                         pEffect->SetFloat( hPower, m_pMaterials[i].Power );\r
2302                     pEffect->CommitChanges();\r
2303                 }\r
2304                 m_pMesh->DrawSubset( i );\r
2305             }\r
2306             pEffect->EndPass();\r
2307         }\r
2308         pEffect->End();\r
2309     }\r
2310 \r
2311     // Then, draw the subsets with alpha\r
2312     if( bDrawAlphaSubsets && m_bUseMaterials )\r
2313     {\r
2314         pEffect->Begin( &cPasses, 0 );\r
2315         for( UINT p = 0; p < cPasses; ++p )\r
2316         {\r
2317             pEffect->BeginPass( p );\r
2318             for( DWORD i = 0; i < m_dwNumMaterials; i++ )\r
2319             {\r
2320                 if( m_bUseMaterials )\r
2321                 {\r
2322                     if( m_pMaterials[i].Diffuse.a == 1.0f )\r
2323                         continue;\r
2324                     if( hTexture )\r
2325                         pEffect->SetTexture( hTexture, m_pTextures[i] );\r
2326                     // D3DCOLORVALUE and D3DXVECTOR4 are data-wise identical.\r
2327                     // No conversion is needed.\r
2328                     if( hDiffuse )\r
2329                         pEffect->SetVector( hDiffuse, ( D3DXVECTOR4* )&m_pMaterials[i].Diffuse );\r
2330                     if( hAmbient )\r
2331                         pEffect->SetVector( hAmbient, ( D3DXVECTOR4* )&m_pMaterials[i].Ambient );\r
2332                     if( hSpecular )\r
2333                         pEffect->SetVector( hSpecular, ( D3DXVECTOR4* )&m_pMaterials[i].Specular );\r
2334                     if( hEmissive )\r
2335                         pEffect->SetVector( hEmissive, ( D3DXVECTOR4* )&m_pMaterials[i].Emissive );\r
2336                     if( hPower )\r
2337                         pEffect->SetFloat( hPower, m_pMaterials[i].Power );\r
2338                     pEffect->CommitChanges();\r
2339                 }\r
2340                 m_pMesh->DrawSubset( i );\r
2341             }\r
2342             pEffect->EndPass();\r
2343         }\r
2344         pEffect->End();\r
2345     }\r
2346 \r
2347     return S_OK;\r
2348 }\r