Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Demos / DX11ClothDemo / DXUT / Optional / SDKmisc.cpp
1 //--------------------------------------------------------------------------------------\r
2 // File: SDKmisc.cpp\r
3 //\r
4 // Various helper functionality that is shared between SDK samples\r
5 //\r
6 // Copyright (c) Microsoft Corporation. All rights reserved\r
7 //--------------------------------------------------------------------------------------\r
8 #include "dxut.h"\r
9 #include "SDKmisc.h"\r
10 #include "DXUTres.h"\r
11 #undef min // use __min instead\r
12 #undef max // use __max instead\r
13 \r
14 #include "DXUTGui.h"\r
15 \r
16 //--------------------------------------------------------------------------------------\r
17 // Global/Static Members\r
18 //--------------------------------------------------------------------------------------\r
19 CDXUTResourceCache& WINAPI DXUTGetGlobalResourceCache()\r
20 {\r
21     // Using an accessor function gives control of the construction order\r
22     static CDXUTResourceCache cache;\r
23     return cache;\r
24 }\r
25 \r
26 \r
27 //--------------------------------------------------------------------------------------\r
28 // Internal functions forward declarations\r
29 //--------------------------------------------------------------------------------------\r
30 bool DXUTFindMediaSearchTypicalDirs( __in_ecount(cchSearch) WCHAR* strSearchPath, \r
31                                      int cchSearch, \r
32                                      __in LPCWSTR strLeaf, \r
33                                      __in WCHAR* strExePath,\r
34                                      __in WCHAR* strExeName );\r
35 bool DXUTFindMediaSearchParentDirs( __in_ecount(cchSearch) WCHAR* strSearchPath, \r
36                                     int cchSearch, \r
37                                     __in WCHAR* strStartAt, \r
38                                     __in WCHAR* strLeafName );\r
39 INT_PTR CALLBACK DisplaySwitchToREFWarningProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam );\r
40 \r
41 \r
42 //--------------------------------------------------------------------------------------\r
43 // Shared code for samples to ask user if they want to use a REF device or quit\r
44 //--------------------------------------------------------------------------------------\r
45 void WINAPI DXUTDisplaySwitchingToREFWarning( DXUTDeviceVersion ver )\r
46 {\r
47     if( DXUTGetShowMsgBoxOnError() )\r
48     {\r
49         DWORD dwSkipWarning = 0, dwRead = 0, dwWritten = 0;\r
50         HANDLE hFile = NULL;\r
51 \r
52         // Read previous user settings\r
53         WCHAR strPath[MAX_PATH];\r
54         SHGetFolderPath( DXUTGetHWND(), CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, strPath );\r
55         wcscat_s( strPath, MAX_PATH, L"\\DXUT\\SkipRefWarning.dat" );\r
56         if( ( hFile = CreateFile( strPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0,\r
57                                   NULL ) ) != INVALID_HANDLE_VALUE )\r
58         {\r
59             ReadFile( hFile, &dwSkipWarning, sizeof( DWORD ), &dwRead, NULL );\r
60             CloseHandle( hFile );\r
61         }\r
62 \r
63         if( dwSkipWarning == 0 )\r
64         {\r
65             // Compact code to create a custom dialog box without using a template in a resource file.\r
66             // If this dialog were in a .rc file, this would be a lot simpler but every sample calling this function would\r
67             // need a copy of the dialog in its own .rc file. Also MessageBox API could be used here instead, but \r
68             // the MessageBox API is simpler to call but it can't provide a "Don't show again" checkbox\r
69             typedef struct\r
70             {\r
71                 DLGITEMTEMPLATE a;\r
72                 WORD b;\r
73                 WORD c;\r
74                 WORD d;\r
75                 WORD e;\r
76                 WORD f;\r
77             } DXUT_DLG_ITEM;\r
78             typedef struct\r
79             {\r
80                 DLGTEMPLATE a;\r
81                 WORD b;\r
82                 WORD c;\r
83                 WCHAR   d[2];\r
84                 WORD e;\r
85                 WCHAR   f[16];\r
86                 DXUT_DLG_ITEM i1;\r
87                 DXUT_DLG_ITEM i2;\r
88                 DXUT_DLG_ITEM i3;\r
89                 DXUT_DLG_ITEM i4;\r
90                 DXUT_DLG_ITEM i5;\r
91             } DXUT_DLG_DATA;\r
92 \r
93             DXUT_DLG_DATA dtp =\r
94             {\r
95                 {WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_SYSMENU | DS_ABSALIGN | DS_3DLOOK | DS_SETFONT |\r
96                     DS_MODALFRAME | DS_CENTER,0,5,0,0,269,82},0,0,L" ",8,L"MS Shell Dlg 2",\r
97                 { {WS_CHILD | WS_VISIBLE | SS_ICON | SS_CENTERIMAGE,0,7,7,24,24,0x100},0xFFFF,0x0082,0,0,0}, // icon\r
98                 { {WS_CHILD | WS_VISIBLE,0,40,7,230,25,0x101},0xFFFF,0x0082,0,0,0}, // static text\r
99                 { {WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON,0,80,39,50,14,IDYES},0xFFFF,0x0080,0,0,0}, // Yes button\r
100                 { {WS_CHILD | WS_VISIBLE | WS_TABSTOP,0,133,39,50,14,IDNO},0xFFFF,0x0080,0,0,0}, // No button\r
101                 { {WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_CHECKBOX,0,7,59,70,16,IDIGNORE},0xFFFF,0x0080,0,0,0}, // checkbox\r
102             };\r
103 \r
104             LPARAM lParam;\r
105             if( ver == DXUT_D3D9_DEVICE )\r
106                 lParam = 9;\r
107             else\r
108                 lParam = 11;\r
109             int nResult = ( int )DialogBoxIndirectParam( DXUTGetHINSTANCE(), ( DLGTEMPLATE* )&dtp, DXUTGetHWND(),\r
110                                                          DisplaySwitchToREFWarningProc, lParam );\r
111 \r
112             if( ( nResult & 0x80 ) == 0x80 ) // "Don't show again" checkbox was checked\r
113             {\r
114                 // Save user settings\r
115                 dwSkipWarning = 1;\r
116                 SHGetFolderPath( DXUTGetHWND(), CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, strPath );\r
117                 wcscat_s( strPath, MAX_PATH, L"\\DXUT" );\r
118                 CreateDirectory( strPath, NULL );\r
119                 wcscat_s( strPath, MAX_PATH, L"\\SkipRefWarning.dat" );\r
120                 if( ( hFile = CreateFile( strPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0,\r
121                                           NULL ) ) != INVALID_HANDLE_VALUE )\r
122                 {\r
123                     WriteFile( hFile, &dwSkipWarning, sizeof( DWORD ), &dwWritten, NULL );\r
124                     CloseHandle( hFile );\r
125                 }\r
126             }\r
127 \r
128             // User choose not to continue\r
129             if( ( nResult & 0x0F ) == IDNO )\r
130                 DXUTShutdown( 1 );\r
131         }\r
132     }\r
133 }\r
134 \r
135 \r
136 //--------------------------------------------------------------------------------------\r
137 // MsgProc for DXUTDisplaySwitchingToREFWarning() dialog box\r
138 //--------------------------------------------------------------------------------------\r
139 INT_PTR CALLBACK DisplaySwitchToREFWarningProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )\r
140 {\r
141     switch( message )\r
142     {\r
143         case WM_INITDIALOG:\r
144             // Easier to set text here than in the DLGITEMTEMPLATE\r
145             SetWindowText( hDlg, DXUTGetWindowTitle() );\r
146             SendMessage( GetDlgItem( hDlg, 0x100 ), STM_SETIMAGE, IMAGE_ICON, ( LPARAM )LoadIcon( 0, IDI_QUESTION ) );\r
147             WCHAR sz[512];\r
148             swprintf_s( sz, 512,\r
149                              L"This program needs to use the Direct3D %d reference device.  This device implements the entire Direct3D %d feature set, but runs very slowly.  Do you wish to continue?", lParam, lParam );\r
150             SetDlgItemText( hDlg, 0x101, sz );\r
151             SetDlgItemText( hDlg, IDYES, L"&Yes" );\r
152             SetDlgItemText( hDlg, IDNO, L"&No" );\r
153             SetDlgItemText( hDlg, IDIGNORE, L"&Don't show again" );\r
154             break;\r
155 \r
156         case WM_COMMAND:\r
157             switch( LOWORD( wParam ) )\r
158             {\r
159                 case IDIGNORE:\r
160                     CheckDlgButton( hDlg, IDIGNORE, ( IsDlgButtonChecked( hDlg,\r
161                                                                           IDIGNORE ) == BST_CHECKED ) ? BST_UNCHECKED :\r
162                                     BST_CHECKED );\r
163                     EnableWindow( GetDlgItem( hDlg, IDNO ), ( IsDlgButtonChecked( hDlg, IDIGNORE ) != BST_CHECKED ) );\r
164                     break;\r
165                 case IDNO:\r
166                     EndDialog( hDlg, ( IsDlgButtonChecked( hDlg, IDIGNORE ) == BST_CHECKED ) ? IDNO | 0x80 : IDNO |\r
167                                0x00 ); return TRUE;\r
168                 case IDCANCEL:\r
169                 case IDYES:\r
170                     EndDialog( hDlg, ( IsDlgButtonChecked( hDlg, IDIGNORE ) == BST_CHECKED ) ? IDYES | 0x80 : IDYES |\r
171                                0x00 ); return TRUE;\r
172             }\r
173             break;\r
174     }\r
175     return FALSE;\r
176 }\r
177 \r
178 \r
179 //--------------------------------------------------------------------------------------\r
180 // Returns pointer to static media search buffer\r
181 //--------------------------------------------------------------------------------------\r
182 WCHAR* DXUTMediaSearchPath()\r
183 {\r
184     static WCHAR s_strMediaSearchPath[MAX_PATH] =\r
185     {\r
186         0\r
187     };\r
188     return s_strMediaSearchPath;\r
189 \r
190 }\r
191 \r
192 //--------------------------------------------------------------------------------------\r
193 LPCWSTR WINAPI DXUTGetMediaSearchPath()\r
194 {\r
195     return DXUTMediaSearchPath();\r
196 }\r
197 \r
198 \r
199 //--------------------------------------------------------------------------------------\r
200 HRESULT WINAPI DXUTSetMediaSearchPath( LPCWSTR strPath )\r
201 {\r
202     HRESULT hr;\r
203 \r
204     WCHAR* s_strSearchPath = DXUTMediaSearchPath();\r
205 \r
206     hr = wcscpy_s( s_strSearchPath, MAX_PATH, strPath );\r
207     if( SUCCEEDED( hr ) )\r
208     {\r
209         // append slash if needed\r
210         size_t ch = 0;\r
211         ch = wcsnlen( s_strSearchPath, MAX_PATH);\r
212         if( SUCCEEDED( hr ) && s_strSearchPath[ch - 1] != L'\\' )\r
213         {\r
214             hr = wcscat_s( s_strSearchPath, MAX_PATH, L"\\" );\r
215         }\r
216     }\r
217 \r
218     return hr;\r
219 }\r
220 \r
221 \r
222 //--------------------------------------------------------------------------------------\r
223 // Tries to find the location of a SDK media file\r
224 //       cchDest is the size in WCHARs of strDestPath.  Be careful not to \r
225 //       pass in sizeof(strDest) on UNICODE builds.\r
226 //--------------------------------------------------------------------------------------\r
227 HRESULT WINAPI DXUTFindDXSDKMediaFileCch(__in_ecount(cchDest) WCHAR* strDestPath,\r
228                                          int cchDest, \r
229                                          __in LPCWSTR strFilename )\r
230 {\r
231     bool bFound;\r
232     WCHAR strSearchFor[MAX_PATH];\r
233 \r
234     if( NULL == strFilename || strFilename[0] == 0 || NULL == strDestPath || cchDest < 10 )\r
235         return E_INVALIDARG;\r
236 \r
237     // Get the exe name, and exe path\r
238     WCHAR strExePath[MAX_PATH] =\r
239     {\r
240         0\r
241     };\r
242     WCHAR strExeName[MAX_PATH] =\r
243     {\r
244         0\r
245     };\r
246     WCHAR* strLastSlash = NULL;\r
247     GetModuleFileName( NULL, strExePath, MAX_PATH );\r
248     strExePath[MAX_PATH - 1] = 0;\r
249     strLastSlash = wcsrchr( strExePath, TEXT( '\\' ) );\r
250     if( strLastSlash )\r
251     {\r
252         wcscpy_s( strExeName, MAX_PATH, &strLastSlash[1] );\r
253 \r
254         // Chop the exe name from the exe path\r
255         *strLastSlash = 0;\r
256 \r
257         // Chop the .exe from the exe name\r
258         strLastSlash = wcsrchr( strExeName, TEXT( '.' ) );\r
259         if( strLastSlash )\r
260             *strLastSlash = 0;\r
261     }\r
262 \r
263     // Typical directories:\r
264     //      .\\r
265     //      ..\\r
266     //      ..\..\\r
267     //      %EXE_DIR%\\r
268     //      %EXE_DIR%\..\\r
269     //      %EXE_DIR%\..\..\\r
270     //      %EXE_DIR%\..\%EXE_NAME%\r
271     //      %EXE_DIR%\..\..\%EXE_NAME%\r
272 \r
273     // Typical directory search\r
274     bFound = DXUTFindMediaSearchTypicalDirs( strDestPath, cchDest, strFilename, strExePath, strExeName );\r
275     if( bFound )\r
276         return S_OK;\r
277 \r
278     // Typical directory search again, but also look in a subdir called "\media\" \r
279     swprintf_s( strSearchFor, MAX_PATH, L"media\\%s", strFilename );\r
280     bFound = DXUTFindMediaSearchTypicalDirs( strDestPath, cchDest, strSearchFor, strExePath, strExeName );\r
281     if( bFound )\r
282         return S_OK;\r
283 \r
284     WCHAR strLeafName[MAX_PATH] =\r
285     {\r
286         0\r
287     };\r
288 \r
289     // Search all parent directories starting at .\ and using strFilename as the leaf name\r
290     wcscpy_s( strLeafName, MAX_PATH, strFilename );\r
291     bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, L".", strLeafName );\r
292     if( bFound )\r
293         return S_OK;\r
294 \r
295     // Search all parent directories starting at the exe's dir and using strFilename as the leaf name\r
296     bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, strExePath, strLeafName );\r
297     if( bFound )\r
298         return S_OK;\r
299 \r
300     // Search all parent directories starting at .\ and using "media\strFilename" as the leaf name\r
301     swprintf_s( strLeafName, MAX_PATH, L"media\\%s", strFilename );\r
302     bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, L".", strLeafName );\r
303     if( bFound )\r
304         return S_OK;\r
305 \r
306     // Search all parent directories starting at the exe's dir and using "media\strFilename" as the leaf name\r
307     bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, strExePath, strLeafName );\r
308     if( bFound )\r
309         return S_OK;\r
310 \r
311     // On failure, return the file as the path but also return an error code\r
312     wcscpy_s( strDestPath, cchDest, strFilename );\r
313 \r
314     return DXUTERR_MEDIANOTFOUND;\r
315 }\r
316 \r
317 \r
318 //--------------------------------------------------------------------------------------\r
319 // Search a set of typical directories\r
320 //--------------------------------------------------------------------------------------\r
321 bool DXUTFindMediaSearchTypicalDirs( __in_ecount(cchSearch) WCHAR* strSearchPath, \r
322                                     int cchSearch, \r
323                                     __in LPCWSTR strLeaf, \r
324                                     __in WCHAR* strExePath,\r
325                                     __in WCHAR* strExeName )\r
326 {\r
327     // Typical directories:\r
328     //      .\\r
329     //      ..\\r
330     //      ..\..\\r
331     //      %EXE_DIR%\\r
332     //      %EXE_DIR%\..\\r
333     //      %EXE_DIR%\..\..\\r
334     //      %EXE_DIR%\..\%EXE_NAME%\r
335     //      %EXE_DIR%\..\..\%EXE_NAME%\r
336     //      DXSDK media path\r
337 \r
338     // Search in .\  \r
339     wcscpy_s( strSearchPath, cchSearch, strLeaf );\r
340     if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )\r
341         return true;\r
342 \r
343     // Search in ..\  \r
344     swprintf_s( strSearchPath, cchSearch, L"..\\%s", strLeaf );\r
345     if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )\r
346         return true;\r
347 \r
348     // Search in ..\..\ \r
349     swprintf_s( strSearchPath, cchSearch, L"..\\..\\%s", strLeaf );\r
350     if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )\r
351         return true;\r
352 \r
353     // Search in ..\..\ \r
354     swprintf_s( strSearchPath, cchSearch, L"..\\..\\%s", strLeaf );\r
355     if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )\r
356         return true;\r
357 \r
358     // Search in the %EXE_DIR%\ \r
359     swprintf_s( strSearchPath, cchSearch, L"%s\\%s", strExePath, strLeaf );\r
360     if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )\r
361         return true;\r
362 \r
363     // Search in the %EXE_DIR%\..\ \r
364     swprintf_s( strSearchPath, cchSearch, L"%s\\..\\%s", strExePath, strLeaf );\r
365     if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )\r
366         return true;\r
367 \r
368     // Search in the %EXE_DIR%\..\..\ \r
369     swprintf_s( strSearchPath, cchSearch, L"%s\\..\\..\\%s", strExePath, strLeaf );\r
370     if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )\r
371         return true;\r
372 \r
373     // Search in "%EXE_DIR%\..\%EXE_NAME%\".  This matches the DirectX SDK layout\r
374     swprintf_s( strSearchPath, cchSearch, L"%s\\..\\%s\\%s", strExePath, strExeName, strLeaf );\r
375     if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )\r
376         return true;\r
377 \r
378     // Search in "%EXE_DIR%\..\..\%EXE_NAME%\".  This matches the DirectX SDK layout\r
379     swprintf_s( strSearchPath, cchSearch, L"%s\\..\\..\\%s\\%s", strExePath, strExeName, strLeaf );\r
380     if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )\r
381         return true;\r
382 \r
383         // Search in "%EXE_DIR%\Demos\DX11ClothDemo\Media\".  This matches the Bullet SDK layout\r
384     swprintf_s( strSearchPath, cchSearch, L"%s\\Demos\\DX11ClothDemo\\Media\\%s", strExePath, strLeaf );\r
385     if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )\r
386         return true;\r
387 \r
388         // Search in "%EXE_DIR%\Demos\DX11ClothDemo\".  This matches the Bullet SDK layout\r
389     swprintf_s( strSearchPath, cchSearch, L"%s\\Demos\\DX11ClothDemo\\%s", strExePath, strLeaf );\r
390     if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )\r
391         return true;\r
392 \r
393 \r
394     // Search in media search dir \r
395     WCHAR* s_strSearchPath = DXUTMediaSearchPath();\r
396     if( s_strSearchPath[0] != 0 )\r
397     {\r
398         swprintf_s( strSearchPath, cchSearch, L"%s%s", s_strSearchPath, strLeaf );\r
399         if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )\r
400             return true;\r
401     }\r
402 \r
403     return false;\r
404 }\r
405 \r
406 \r
407 \r
408 //--------------------------------------------------------------------------------------\r
409 // Search parent directories starting at strStartAt, and appending strLeafName\r
410 // at each parent directory.  It stops at the root directory.\r
411 //--------------------------------------------------------------------------------------\r
412 bool DXUTFindMediaSearchParentDirs( __in_ecount(cchSearch) WCHAR* strSearchPath, \r
413                                     int cchSearch, \r
414                                     __in WCHAR* strStartAt, \r
415                                     __in WCHAR* strLeafName )\r
416 {\r
417     WCHAR strFullPath[MAX_PATH] =\r
418     {\r
419         0\r
420     };\r
421     WCHAR strFullFileName[MAX_PATH] =\r
422     {\r
423         0\r
424     };\r
425     WCHAR strSearch[MAX_PATH] =\r
426     {\r
427         0\r
428     };\r
429     WCHAR* strFilePart = NULL;\r
430 \r
431     GetFullPathName( strStartAt, MAX_PATH, strFullPath, &strFilePart );\r
432     if( strFilePart == NULL )\r
433         return false;\r
434 \r
435     while( strFilePart != NULL && *strFilePart != '\0' )\r
436     {\r
437         swprintf_s( strFullFileName, MAX_PATH, L"%s\\%s", strFullPath, strLeafName );\r
438         if( GetFileAttributes( strFullFileName ) != 0xFFFFFFFF )\r
439         {\r
440             wcscpy_s( strSearchPath, cchSearch, strFullFileName );\r
441             return true;\r
442         }\r
443 \r
444         swprintf_s( strSearch, MAX_PATH, L"%s\\..", strFullPath );\r
445         GetFullPathName( strSearch, MAX_PATH, strFullPath, &strFilePart );\r
446     }\r
447 \r
448     return false;\r
449 }\r
450 \r
451 \r
452 //--------------------------------------------------------------------------------------\r
453 // CDXUTResourceCache\r
454 //--------------------------------------------------------------------------------------\r
455 \r
456 //--------------------------------------------------------------------------------------\r
457 CDXUTResourceCache::~CDXUTResourceCache()\r
458 {\r
459     OnDestroyDevice();\r
460 \r
461     m_TextureCache.RemoveAll();\r
462     m_EffectCache.RemoveAll();\r
463     m_FontCache.RemoveAll();\r
464 }\r
465 \r
466 //--------------------------------------------------------------------------------------\r
467 HRESULT CDXUTResourceCache::CreateTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile,\r
468                                                    LPDIRECT3DTEXTURE9* ppTexture )\r
469 {\r
470     return CreateTextureFromFileEx( pDevice, pSrcFile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,\r
471                                     0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,\r
472                                     0, NULL, NULL, ppTexture );\r
473 }\r
474 \r
475 //--------------------------------------------------------------------------------------\r
476 HRESULT CDXUTResourceCache::CreateTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCSTR pSrcFile,\r
477                                                    LPDIRECT3DTEXTURE9* ppTexture )\r
478 {\r
479     WCHAR szSrcFile[MAX_PATH];\r
480     MultiByteToWideChar( CP_ACP, 0, pSrcFile, -1, szSrcFile, MAX_PATH );\r
481     szSrcFile[MAX_PATH - 1] = 0;\r
482 \r
483     return CreateTextureFromFile( pDevice, szSrcFile, ppTexture );\r
484 }\r
485 \r
486 //--------------------------------------------------------------------------------------\r
487 HRESULT CDXUTResourceCache::CreateTextureFromFile( ID3D11Device* pDevice, ID3D11DeviceContext *pContext, LPCTSTR pSrcFile,\r
488                                                    ID3D11ShaderResourceView** ppOutputRV, bool bSRGB )\r
489 {\r
490     return CreateTextureFromFileEx( pDevice, pContext, pSrcFile, NULL, NULL, ppOutputRV, bSRGB );\r
491 }\r
492 \r
493 //--------------------------------------------------------------------------------------\r
494 HRESULT CDXUTResourceCache::CreateTextureFromFile( ID3D11Device* pDevice, ID3D11DeviceContext *pContext, LPCSTR pSrcFile,\r
495                                                    ID3D11ShaderResourceView** ppOutputRV, bool bSRGB )\r
496 {\r
497     WCHAR szSrcFile[MAX_PATH];\r
498     MultiByteToWideChar( CP_ACP, 0, pSrcFile, -1, szSrcFile, MAX_PATH );\r
499     szSrcFile[MAX_PATH - 1] = 0;\r
500 \r
501     return CreateTextureFromFile( pDevice, pContext, szSrcFile, ppOutputRV, bSRGB );\r
502 }\r
503 \r
504 //--------------------------------------------------------------------------------------\r
505 HRESULT CDXUTResourceCache::CreateTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Width,\r
506                                                      UINT Height, UINT MipLevels, DWORD Usage, D3DFORMAT Format,\r
507                                                      D3DPOOL Pool, DWORD Filter, DWORD MipFilter, D3DCOLOR ColorKey,\r
508                                                      D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette,\r
509                                                      LPDIRECT3DTEXTURE9* ppTexture )\r
510 {\r
511     // Search the cache for a matching entry.\r
512     for( int i = 0; i < m_TextureCache.GetSize(); ++i )\r
513     {\r
514         DXUTCache_Texture& Entry = m_TextureCache[i];\r
515         if( Entry.Location == DXUTCACHE_LOCATION_FILE &&\r
516             !lstrcmpW( Entry.wszSource, pSrcFile ) &&\r
517             Entry.Width == Width &&\r
518             Entry.Height == Height &&\r
519             Entry.MipLevels == MipLevels &&\r
520             Entry.Usage9 == Usage &&\r
521             Entry.Format9 == Format &&\r
522             Entry.Pool9 == Pool &&\r
523             Entry.Type9 == D3DRTYPE_TEXTURE )\r
524         {\r
525             // A match is found. Obtain the IDirect3DTexture9 interface and return that.\r
526             return Entry.pTexture9->QueryInterface( IID_IDirect3DTexture9, ( LPVOID* )ppTexture );\r
527         }\r
528     }\r
529 \r
530     HRESULT hr;\r
531 \r
532     // No matching entry.  Load the resource and create a new entry.\r
533     hr = D3DXCreateTextureFromFileEx( pDevice, pSrcFile, Width, Height, MipLevels, Usage, Format,\r
534                                       Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette, ppTexture );\r
535     if( FAILED( hr ) )\r
536         return hr;\r
537 \r
538     DXUTCache_Texture NewEntry;\r
539     NewEntry.Location = DXUTCACHE_LOCATION_FILE;\r
540     wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcFile );\r
541     NewEntry.Width = Width;\r
542     NewEntry.Height = Height;\r
543     NewEntry.MipLevels = MipLevels;\r
544     NewEntry.Usage9 = Usage;\r
545     NewEntry.Format9 = Format;\r
546     NewEntry.Pool9 = Pool;\r
547     NewEntry.Type9 = D3DRTYPE_TEXTURE;\r
548     ( *ppTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 );\r
549 \r
550     m_TextureCache.Add( NewEntry );\r
551     return S_OK;\r
552 }\r
553 \r
554 \r
555 \r
556 //--------------------------------------------------------------------------------------\r
557 HRESULT CDXUTResourceCache::CreateTextureFromFileEx( ID3D11Device* pDevice, ID3D11DeviceContext* pContext, LPCTSTR pSrcFile,\r
558                                                      D3DX11_IMAGE_LOAD_INFO* pLoadInfo, ID3DX11ThreadPump* pPump,\r
559                                                      ID3D11ShaderResourceView** ppOutputRV, bool bSRGB )\r
560 {\r
561 \r
562     bool is10L9 = DXUTGetDeviceSettings().d3d11.DeviceFeatureLevel < D3D_FEATURE_LEVEL_10_0; \r
563     HRESULT hr = S_OK;\r
564     D3DX11_IMAGE_LOAD_INFO ZeroInfo;    //D3DX11_IMAGE_LOAD_INFO has a default constructor\r
565     D3DX11_IMAGE_INFO SrcInfo;\r
566 \r
567     if( !pLoadInfo )\r
568     {\r
569         pLoadInfo = &ZeroInfo;\r
570     }\r
571 \r
572     if( !pLoadInfo->pSrcInfo )\r
573     {\r
574         D3DX11GetImageInfoFromFile( pSrcFile, NULL, &SrcInfo, NULL );\r
575         pLoadInfo->pSrcInfo = &SrcInfo;\r
576 \r
577         pLoadInfo->Format = pLoadInfo->pSrcInfo->Format;\r
578     }\r
579 \r
580     // Search the cache for a matching entry.\r
581     for( int i = 0; i < m_TextureCache.GetSize(); ++i )\r
582     {\r
583         DXUTCache_Texture& Entry = m_TextureCache[i];\r
584         if( Entry.Location == DXUTCACHE_LOCATION_FILE &&\r
585             !lstrcmpW( Entry.wszSource, pSrcFile ) &&\r
586             Entry.Width == pLoadInfo->Width &&\r
587             Entry.Height == pLoadInfo->Height &&\r
588             Entry.MipLevels == pLoadInfo->MipLevels &&\r
589             Entry.Usage11 == pLoadInfo->Usage &&\r
590             Entry.Format == pLoadInfo->Format &&\r
591             Entry.CpuAccessFlags == pLoadInfo->CpuAccessFlags &&\r
592             Entry.BindFlags == pLoadInfo->BindFlags &&\r
593             Entry.MiscFlags == pLoadInfo->MiscFlags )\r
594         {\r
595             // A match is found. Obtain the IDirect3DTexture9 interface and return that.\r
596             return Entry.pSRV11->QueryInterface( __uuidof( ID3D11ShaderResourceView ), ( LPVOID* )ppOutputRV );\r
597         }\r
598     }\r
599 \r
600     //Ready a new entry to the texture cache\r
601     //Do this before creating the texture since pLoadInfo may be volatile\r
602     DXUTCache_Texture NewEntry;\r
603     NewEntry.Location = DXUTCACHE_LOCATION_FILE;\r
604     wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcFile );\r
605     NewEntry.Width = pLoadInfo->Width;\r
606     NewEntry.Height = pLoadInfo->Height;\r
607     NewEntry.MipLevels = pLoadInfo->MipLevels;\r
608     NewEntry.Usage11 = pLoadInfo->Usage;\r
609     // 10L9 can't handle typesless, so we cant make a typesless format \r
610     if (is10L9 && bSRGB) {\r
611         NewEntry.Format = MAKE_SRGB(pLoadInfo->Format);\r
612     }else {\r
613         NewEntry.Format = pLoadInfo->Format;\r
614     }\r
615     NewEntry.CpuAccessFlags = pLoadInfo->CpuAccessFlags;\r
616     NewEntry.BindFlags = pLoadInfo->BindFlags;\r
617     NewEntry.MiscFlags = pLoadInfo->MiscFlags;\r
618 \r
619     //Create the rexture\r
620     ID3D11Texture2D* pRes = NULL;\r
621     hr = D3DX11CreateTextureFromFile( pDevice, pSrcFile, pLoadInfo, pPump, ( ID3D11Resource** )&pRes, NULL );\r
622 \r
623     if( FAILED( hr ) )\r
624         return hr;\r
625     D3D11_TEXTURE2D_DESC tex_dsc;\r
626     pRes->GetDesc(&tex_dsc);\r
627 \r
628 \r
629 \r
630     if (bSRGB ) {\r
631         // This is a workaround so that we can load linearly, but sample in SRGB.  Right now, we can't load\r
632         // as linear since D3DX will try to do conversion on load.  Loading as TYPELESS doesn't work either, and\r
633         // loading as typed _UNORM doesn't allow us to create an SRGB view.\r
634 \r
635         // on d3d11 featuer levels this is just a copy, but on 10L9 we must use a cpu side copy with 2 staging resources.\r
636         ID3D11Texture2D* unormStaging = NULL;\r
637         ID3D11Texture2D* srgbStaging = NULL;\r
638 \r
639         D3D11_TEXTURE2D_DESC CopyDesc;\r
640         pRes->GetDesc( &CopyDesc );\r
641 \r
642         pLoadInfo->BindFlags = 0;\r
643         pLoadInfo->CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;\r
644         pLoadInfo->Depth = 0;\r
645         pLoadInfo->Filter = D3DX11_FILTER_POINT;\r
646         pLoadInfo->FirstMipLevel = 0;\r
647         pLoadInfo->Format = CopyDesc.Format;\r
648         pLoadInfo->Height = CopyDesc.Height;\r
649         pLoadInfo->MipFilter = D3DX11_FILTER_POINT;\r
650         pLoadInfo->MiscFlags = CopyDesc.MiscFlags;\r
651         pLoadInfo->Usage = D3D11_USAGE_STAGING;\r
652         pLoadInfo->Width = CopyDesc.Width;\r
653 \r
654         CopyDesc.BindFlags = 0;\r
655         CopyDesc.Usage = D3D11_USAGE_STAGING;\r
656         CopyDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;\r
657         CopyDesc.Format = MAKE_SRGB(CopyDesc.Format);\r
658 \r
659         hr = D3DX11CreateTextureFromFile( pDevice, pSrcFile, pLoadInfo, pPump, ( ID3D11Resource** )&unormStaging, NULL );\r
660 \r
661         hr = pDevice->CreateTexture2D(&CopyDesc, NULL, &srgbStaging);\r
662         pContext->CopyResource( srgbStaging, unormStaging );\r
663         ID3D11Texture2D* srgbGPU;\r
664 \r
665         pRes->GetDesc( &CopyDesc );\r
666         CopyDesc.Format = MAKE_SRGB(CopyDesc.Format);\r
667         hr = pDevice->CreateTexture2D(&CopyDesc, NULL, &srgbGPU);\r
668         pContext->CopyResource( srgbGPU, srgbStaging );\r
669 \r
670         SAFE_RELEASE(pRes);\r
671         SAFE_RELEASE(srgbStaging);\r
672         SAFE_RELEASE(unormStaging);\r
673         pRes = srgbGPU;\r
674 \r
675     }\r
676 \r
677     D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;\r
678     if( bSRGB )\r
679         SRVDesc.Format = MAKE_SRGB( ZeroInfo.Format );\r
680     else\r
681         SRVDesc.Format = ZeroInfo.Format;\r
682     if( pLoadInfo->pSrcInfo->ResourceDimension == D3D11_RESOURCE_DIMENSION_TEXTURE1D )\r
683     {\r
684         SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;\r
685         SRVDesc.Texture1D.MostDetailedMip = 0;\r
686         SRVDesc.Texture1D.MipLevels = pLoadInfo->pSrcInfo->MipLevels;\r
687     }\r
688     else if( pLoadInfo->pSrcInfo->ResourceDimension == D3D11_RESOURCE_DIMENSION_TEXTURE2D )\r
689     {\r
690         SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;\r
691         SRVDesc.Texture2D.MostDetailedMip = 0;\r
692         SRVDesc.Texture2D.MipLevels = pLoadInfo->pSrcInfo->MipLevels;\r
693 \r
694         if( pLoadInfo->pSrcInfo->MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE )\r
695         {\r
696             SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;\r
697             SRVDesc.TextureCube.MostDetailedMip = 0;\r
698             SRVDesc.TextureCube.MipLevels = pLoadInfo->pSrcInfo->MipLevels;\r
699         }\r
700     }\r
701     else if( pLoadInfo->pSrcInfo->ResourceDimension == D3D11_RESOURCE_DIMENSION_TEXTURE3D )\r
702     {\r
703         SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;\r
704         SRVDesc.Texture3D.MostDetailedMip = 0;\r
705         SRVDesc.Texture3D.MipLevels = pLoadInfo->pSrcInfo->MipLevels;\r
706     }\r
707     if (bSRGB) {\r
708         SRVDesc.Format = MAKE_SRGB(tex_dsc.Format);\r
709     }else {\r
710         SRVDesc.Format = tex_dsc.Format;\r
711     }\r
712     SRVDesc.Texture2D.MipLevels = tex_dsc.MipLevels;\r
713     SRVDesc.Texture2D.MostDetailedMip = 0;\r
714     hr = pDevice->CreateShaderResourceView( pRes, &SRVDesc, ppOutputRV );\r
715     pRes->Release();\r
716     if( FAILED( hr ) )\r
717         return hr;\r
718 \r
719     ( *ppOutputRV )->QueryInterface( __uuidof( ID3D11ShaderResourceView ), ( LPVOID* )&NewEntry.pSRV11 );\r
720 \r
721     m_TextureCache.Add( NewEntry );\r
722 \r
723     return S_OK;\r
724 }\r
725 \r
726 \r
727 //--------------------------------------------------------------------------------------\r
728 HRESULT CDXUTResourceCache::CreateTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,\r
729                                                        LPCTSTR pSrcResource, LPDIRECT3DTEXTURE9* ppTexture )\r
730 {\r
731     return CreateTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, D3DX_DEFAULT, D3DX_DEFAULT,\r
732                                         D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT,\r
733                                         D3DX_DEFAULT, 0, NULL, NULL, ppTexture );\r
734 }\r
735 \r
736 \r
737 //--------------------------------------------------------------------------------------\r
738 HRESULT CDXUTResourceCache::CreateTextureFromResourceEx( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,\r
739                                                          LPCTSTR pSrcResource, UINT Width, UINT Height, UINT MipLevels,\r
740                                                          DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, DWORD Filter,\r
741                                                          DWORD MipFilter, D3DCOLOR ColorKey, D3DXIMAGE_INFO* pSrcInfo,\r
742                                                          PALETTEENTRY* pPalette, LPDIRECT3DTEXTURE9* ppTexture )\r
743 {\r
744     // Search the cache for a matching entry.\r
745     for( int i = 0; i < m_TextureCache.GetSize(); ++i )\r
746     {\r
747         DXUTCache_Texture& Entry = m_TextureCache[i];\r
748         if( Entry.Location == DXUTCACHE_LOCATION_RESOURCE &&\r
749             Entry.hSrcModule == hSrcModule &&\r
750             !lstrcmpW( Entry.wszSource, pSrcResource ) &&\r
751             Entry.Width == Width &&\r
752             Entry.Height == Height &&\r
753             Entry.MipLevels == MipLevels &&\r
754             Entry.Usage9 == Usage &&\r
755             Entry.Format9 == Format &&\r
756             Entry.Pool9 == Pool &&\r
757             Entry.Type9 == D3DRTYPE_TEXTURE )\r
758         {\r
759             // A match is found. Obtain the IDirect3DTexture9 interface and return that.\r
760             return Entry.pTexture9->QueryInterface( IID_IDirect3DTexture9, ( LPVOID* )ppTexture );\r
761         }\r
762     }\r
763 \r
764     HRESULT hr;\r
765 \r
766     // No matching entry.  Load the resource and create a new entry.\r
767     hr = D3DXCreateTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, Width, Height, MipLevels, Usage,\r
768                                           Format, Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette, ppTexture );\r
769     if( FAILED( hr ) )\r
770         return hr;\r
771 \r
772     DXUTCache_Texture NewEntry;\r
773     NewEntry.Location = DXUTCACHE_LOCATION_RESOURCE;\r
774     NewEntry.hSrcModule = hSrcModule;\r
775     wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcResource );\r
776     NewEntry.Width = Width;\r
777     NewEntry.Height = Height;\r
778     NewEntry.MipLevels = MipLevels;\r
779     NewEntry.Usage9 = Usage;\r
780     NewEntry.Format9 = Format;\r
781     NewEntry.Pool9 = Pool;\r
782     NewEntry.Type9 = D3DRTYPE_TEXTURE;\r
783     ( *ppTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 );\r
784 \r
785     m_TextureCache.Add( NewEntry );\r
786     return S_OK;\r
787 }\r
788 \r
789 \r
790 //--------------------------------------------------------------------------------------\r
791 HRESULT CDXUTResourceCache::CreateCubeTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile,\r
792                                                        LPDIRECT3DCUBETEXTURE9* ppCubeTexture )\r
793 {\r
794     return CreateCubeTextureFromFileEx( pDevice, pSrcFile, D3DX_DEFAULT, D3DX_DEFAULT, 0,\r
795                                         D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,\r
796                                         0, NULL, NULL, ppCubeTexture );\r
797 }\r
798 \r
799 \r
800 //--------------------------------------------------------------------------------------\r
801 HRESULT CDXUTResourceCache::CreateCubeTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Size,\r
802                                                          UINT MipLevels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool,\r
803                                                          DWORD Filter, DWORD MipFilter, D3DCOLOR ColorKey,\r
804                                                          D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette,\r
805                                                          LPDIRECT3DCUBETEXTURE9* ppCubeTexture )\r
806 {\r
807     // Search the cache for a matching entry.\r
808     for( int i = 0; i < m_TextureCache.GetSize(); ++i )\r
809     {\r
810         DXUTCache_Texture& Entry = m_TextureCache[i];\r
811         if( Entry.Location == DXUTCACHE_LOCATION_FILE &&\r
812             !lstrcmpW( Entry.wszSource, pSrcFile ) &&\r
813             Entry.Width == Size &&\r
814             Entry.MipLevels == MipLevels &&\r
815             Entry.Usage9 == Usage &&\r
816             Entry.Format9 == Format &&\r
817             Entry.Pool9 == Pool &&\r
818             Entry.Type9 == D3DRTYPE_CUBETEXTURE )\r
819         {\r
820             // A match is found. Obtain the IDirect3DCubeTexture9 interface and return that.\r
821             return Entry.pTexture9->QueryInterface( IID_IDirect3DCubeTexture9, ( LPVOID* )ppCubeTexture );\r
822         }\r
823     }\r
824 \r
825     HRESULT hr;\r
826 \r
827     // No matching entry.  Load the resource and create a new entry.\r
828     hr = D3DXCreateCubeTextureFromFileEx( pDevice, pSrcFile, Size, MipLevels, Usage, Format, Pool, Filter,\r
829                                           MipFilter, ColorKey, pSrcInfo, pPalette, ppCubeTexture );\r
830     if( FAILED( hr ) )\r
831         return hr;\r
832 \r
833     DXUTCache_Texture NewEntry;\r
834     NewEntry.Location = DXUTCACHE_LOCATION_FILE;\r
835     wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcFile );\r
836     NewEntry.Width = Size;\r
837     NewEntry.MipLevels = MipLevels;\r
838     NewEntry.Usage9 = Usage;\r
839     NewEntry.Format9 = Format;\r
840     NewEntry.Pool9 = Pool;\r
841     NewEntry.Type9 = D3DRTYPE_CUBETEXTURE;\r
842     ( *ppCubeTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 );\r
843 \r
844     m_TextureCache.Add( NewEntry );\r
845     return S_OK;\r
846 }\r
847 \r
848 \r
849 //--------------------------------------------------------------------------------------\r
850 HRESULT CDXUTResourceCache::CreateCubeTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,\r
851                                                            LPCTSTR pSrcResource,\r
852                                                            LPDIRECT3DCUBETEXTURE9* ppCubeTexture )\r
853 {\r
854     return CreateCubeTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, D3DX_DEFAULT, D3DX_DEFAULT,\r
855                                             0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,\r
856                                             0, NULL, NULL, ppCubeTexture );\r
857 }\r
858 \r
859 \r
860 //--------------------------------------------------------------------------------------\r
861 HRESULT CDXUTResourceCache::CreateCubeTextureFromResourceEx( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,\r
862                                                              LPCTSTR pSrcResource, UINT Size, UINT MipLevels,\r
863                                                              DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, DWORD Filter,\r
864                                                              DWORD MipFilter, D3DCOLOR ColorKey,\r
865                                                              D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette,\r
866                                                              LPDIRECT3DCUBETEXTURE9* ppCubeTexture )\r
867 {\r
868     // Search the cache for a matching entry.\r
869     for( int i = 0; i < m_TextureCache.GetSize(); ++i )\r
870     {\r
871         DXUTCache_Texture& Entry = m_TextureCache[i];\r
872         if( Entry.Location == DXUTCACHE_LOCATION_RESOURCE &&\r
873             Entry.hSrcModule == hSrcModule &&\r
874             !lstrcmpW( Entry.wszSource, pSrcResource ) &&\r
875             Entry.Width == Size &&\r
876             Entry.MipLevels == MipLevels &&\r
877             Entry.Usage9 == Usage &&\r
878             Entry.Format9 == Format &&\r
879             Entry.Pool9 == Pool &&\r
880             Entry.Type9 == D3DRTYPE_CUBETEXTURE )\r
881         {\r
882             // A match is found. Obtain the IDirect3DCubeTexture9 interface and return that.\r
883             return Entry.pTexture9->QueryInterface( IID_IDirect3DCubeTexture9, ( LPVOID* )ppCubeTexture );\r
884         }\r
885     }\r
886 \r
887     HRESULT hr;\r
888 \r
889     // No matching entry.  Load the resource and create a new entry.\r
890     hr = D3DXCreateCubeTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, Size, MipLevels, Usage, Format,\r
891                                               Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette, ppCubeTexture );\r
892     if( FAILED( hr ) )\r
893         return hr;\r
894 \r
895     DXUTCache_Texture NewEntry;\r
896     NewEntry.Location = DXUTCACHE_LOCATION_RESOURCE;\r
897     NewEntry.hSrcModule = hSrcModule;\r
898     wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcResource );\r
899     NewEntry.Width = Size;\r
900     NewEntry.MipLevels = MipLevels;\r
901     NewEntry.Usage9 = Usage;\r
902     NewEntry.Format9 = Format;\r
903     NewEntry.Pool9 = Pool;\r
904     NewEntry.Type9 = D3DRTYPE_CUBETEXTURE;\r
905     ( *ppCubeTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 );\r
906 \r
907     m_TextureCache.Add( NewEntry );\r
908     return S_OK;\r
909 }\r
910 \r
911 \r
912 //--------------------------------------------------------------------------------------\r
913 HRESULT CDXUTResourceCache::CreateVolumeTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile,\r
914                                                          LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture )\r
915 {\r
916     return CreateVolumeTextureFromFileEx( pDevice, pSrcFile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,\r
917                                           0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,\r
918                                           0, NULL, NULL, ppVolumeTexture );\r
919 }\r
920 \r
921 \r
922 //--------------------------------------------------------------------------------------\r
923 HRESULT CDXUTResourceCache::CreateVolumeTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Width,\r
924                                                            UINT Height, UINT Depth, UINT MipLevels, DWORD Usage,\r
925                                                            D3DFORMAT Format, D3DPOOL Pool, DWORD Filter,\r
926                                                            DWORD MipFilter, D3DCOLOR ColorKey,\r
927                                                            D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette,\r
928                                                            LPDIRECT3DVOLUMETEXTURE9* ppTexture )\r
929 {\r
930     // Search the cache for a matching entry.\r
931     for( int i = 0; i < m_TextureCache.GetSize(); ++i )\r
932     {\r
933         DXUTCache_Texture& Entry = m_TextureCache[i];\r
934         if( Entry.Location == DXUTCACHE_LOCATION_FILE &&\r
935             !lstrcmpW( Entry.wszSource, pSrcFile ) &&\r
936             Entry.Width == Width &&\r
937             Entry.Height == Height &&\r
938             Entry.Depth == Depth &&\r
939             Entry.MipLevels == MipLevels &&\r
940             Entry.Usage9 == Usage &&\r
941             Entry.Format9 == Format &&\r
942             Entry.Pool9 == Pool &&\r
943             Entry.Type9 == D3DRTYPE_VOLUMETEXTURE )\r
944         {\r
945             // A match is found. Obtain the IDirect3DVolumeTexture9 interface and return that.\r
946             return Entry.pTexture9->QueryInterface( IID_IDirect3DVolumeTexture9, ( LPVOID* )ppTexture );\r
947         }\r
948     }\r
949 \r
950     HRESULT hr;\r
951 \r
952     // No matching entry.  Load the resource and create a new entry.\r
953     hr = D3DXCreateVolumeTextureFromFileEx( pDevice, pSrcFile, Width, Height, Depth, MipLevels, Usage, Format,\r
954                                             Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette, ppTexture );\r
955     if( FAILED( hr ) )\r
956         return hr;\r
957 \r
958     DXUTCache_Texture NewEntry;\r
959     NewEntry.Location = DXUTCACHE_LOCATION_FILE;\r
960     wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcFile );\r
961     NewEntry.Width = Width;\r
962     NewEntry.Height = Height;\r
963     NewEntry.Depth = Depth;\r
964     NewEntry.MipLevels = MipLevels;\r
965     NewEntry.Usage9 = Usage;\r
966     NewEntry.Format9 = Format;\r
967     NewEntry.Pool9 = Pool;\r
968     NewEntry.Type9 = D3DRTYPE_VOLUMETEXTURE;\r
969     ( *ppTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 );\r
970 \r
971     m_TextureCache.Add( NewEntry );\r
972     return S_OK;\r
973 }\r
974 \r
975 \r
976 //--------------------------------------------------------------------------------------\r
977 HRESULT CDXUTResourceCache::CreateVolumeTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,\r
978                                                              LPCTSTR pSrcResource,\r
979                                                              LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture )\r
980 {\r
981     return CreateVolumeTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, D3DX_DEFAULT, D3DX_DEFAULT,\r
982                                               D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED,\r
983                                               D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, ppVolumeTexture );\r
984 }\r
985 \r
986 \r
987 //--------------------------------------------------------------------------------------\r
988 HRESULT CDXUTResourceCache::CreateVolumeTextureFromResourceEx( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,\r
989                                                                LPCTSTR pSrcResource, UINT Width, UINT Height,\r
990                                                                UINT Depth, UINT MipLevels, DWORD Usage,\r
991                                                                D3DFORMAT Format, D3DPOOL Pool, DWORD Filter,\r
992                                                                DWORD MipFilter, D3DCOLOR ColorKey,\r
993                                                                D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette,\r
994                                                                LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture )\r
995 {\r
996     // Search the cache for a matching entry.\r
997     for( int i = 0; i < m_TextureCache.GetSize(); ++i )\r
998     {\r
999         DXUTCache_Texture& Entry = m_TextureCache[i];\r
1000         if( Entry.Location == DXUTCACHE_LOCATION_RESOURCE &&\r
1001             Entry.hSrcModule == hSrcModule &&\r
1002             !lstrcmpW( Entry.wszSource, pSrcResource ) &&\r
1003             Entry.Width == Width &&\r
1004             Entry.Height == Height &&\r
1005             Entry.Depth == Depth &&\r
1006             Entry.MipLevels == MipLevels &&\r
1007             Entry.Usage9 == Usage &&\r
1008             Entry.Format9 == Format &&\r
1009             Entry.Pool9 == Pool &&\r
1010             Entry.Type9 == D3DRTYPE_VOLUMETEXTURE )\r
1011         {\r
1012             // A match is found. Obtain the IDirect3DVolumeTexture9 interface and return that.\r
1013             return Entry.pTexture9->QueryInterface( IID_IDirect3DVolumeTexture9, ( LPVOID* )ppVolumeTexture );\r
1014         }\r
1015     }\r
1016 \r
1017     HRESULT hr;\r
1018 \r
1019     // No matching entry.  Load the resource and create a new entry.\r
1020     hr = D3DXCreateVolumeTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, Width, Height, Depth, MipLevels,\r
1021                                                 Usage,\r
1022                                                 Format, Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette,\r
1023                                                 ppVolumeTexture );\r
1024     if( FAILED( hr ) )\r
1025         return hr;\r
1026 \r
1027     DXUTCache_Texture NewEntry;\r
1028     NewEntry.Location = DXUTCACHE_LOCATION_RESOURCE;\r
1029     NewEntry.hSrcModule = hSrcModule;\r
1030     wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcResource );\r
1031     NewEntry.Width = Width;\r
1032     NewEntry.Height = Height;\r
1033     NewEntry.Depth = Depth;\r
1034     NewEntry.MipLevels = MipLevels;\r
1035     NewEntry.Usage9 = Usage;\r
1036     NewEntry.Format9 = Format;\r
1037     NewEntry.Pool9 = Pool;\r
1038     NewEntry.Type9 = D3DRTYPE_VOLUMETEXTURE;\r
1039     ( *ppVolumeTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 );\r
1040 \r
1041     m_TextureCache.Add( NewEntry );\r
1042     return S_OK;\r
1043 }\r
1044 \r
1045 \r
1046 //--------------------------------------------------------------------------------------\r
1047 HRESULT CDXUTResourceCache::CreateFont( LPDIRECT3DDEVICE9 pDevice, UINT Height, UINT Width, UINT Weight,\r
1048                                         UINT MipLevels, BOOL Italic, DWORD CharSet, DWORD OutputPrecision,\r
1049                                         DWORD Quality, DWORD PitchAndFamily, LPCTSTR pFacename, LPD3DXFONT* ppFont )\r
1050 {\r
1051     D3DXFONT_DESCW Desc;\r
1052 \r
1053     Desc.Height = Height;\r
1054     Desc.Width = Width;\r
1055     Desc.Weight = Weight;\r
1056     Desc.MipLevels = MipLevels;\r
1057     Desc.Italic = Italic;\r
1058     Desc.CharSet = ( BYTE )CharSet;\r
1059     Desc.OutputPrecision = ( BYTE )OutputPrecision;\r
1060     Desc.Quality = ( BYTE )Quality;\r
1061     Desc.PitchAndFamily = ( BYTE )PitchAndFamily;\r
1062     wcscpy_s( Desc.FaceName, LF_FACESIZE, pFacename );\r
1063 \r
1064     return CreateFontIndirect( pDevice, &Desc, ppFont );\r
1065 }\r
1066 \r
1067 \r
1068 //--------------------------------------------------------------------------------------\r
1069 HRESULT CDXUTResourceCache::CreateFontIndirect( LPDIRECT3DDEVICE9 pDevice, CONST D3DXFONT_DESC *pDesc, LPD3DXFONT *ppFont )\r
1070  {\r
1071     // Search the cache for a matching entry.\r
1072     for( int i = 0; i < m_FontCache.GetSize(); ++i )\r
1073  {\r
1074         DXUTCache_Font &Entry = m_FontCache[i];\r
1075 \r
1076         if( Entry.Width == pDesc->Width &&\r
1077             Entry.Height == pDesc->Height &&\r
1078             Entry.Weight == pDesc->Weight &&\r
1079             Entry.MipLevels == pDesc->MipLevels &&\r
1080             Entry.Italic == pDesc->Italic &&\r
1081             Entry.CharSet == pDesc->CharSet &&\r
1082             Entry.OutputPrecision == pDesc->OutputPrecision &&\r
1083             Entry.Quality == pDesc->Quality &&\r
1084             Entry.PitchAndFamily == pDesc->PitchAndFamily &&\r
1085             CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE,\r
1086                            Entry.FaceName, -1,\r
1087                            pDesc->FaceName, -1 ) == CSTR_EQUAL )\r
1088  {\r
1089     // A match is found.  Increment the reference and return the ID3DXFont object.\r
1090             Entry.pFont->AddRef();\r
1091             *ppFont = Entry.pFont;\r
1092             return S_OK;\r
1093         }\r
1094     }\r
1095 \r
1096     HRESULT hr;\r
1097 \r
1098     // No matching entry.  Load the resource and create a new entry.\r
1099     hr = D3DXCreateFontIndirect( pDevice, pDesc, ppFont );\r
1100     if( FAILED( hr ) )\r
1101         return hr;\r
1102 \r
1103     DXUTCache_Font NewEntry;\r
1104     ( D3DXFONT_DESC & )NewEntry = *pDesc;\r
1105     NewEntry.pFont = *ppFont;\r
1106     NewEntry.pFont->AddRef();\r
1107 \r
1108     m_FontCache.Add( NewEntry );\r
1109     return S_OK;\r
1110 }\r
1111 \r
1112 \r
1113 //--------------------------------------------------------------------------------------\r
1114 HRESULT CDXUTResourceCache::CreateEffectFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile,\r
1115                                                   const D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags,\r
1116                                                   LPD3DXEFFECTPOOL pPool, LPD3DXEFFECT* ppEffect,\r
1117                                                   LPD3DXBUFFER* ppCompilationErrors )\r
1118 {\r
1119     // Search the cache for a matching entry.\r
1120     for( int i = 0; i < m_EffectCache.GetSize(); ++i )\r
1121     {\r
1122         DXUTCache_Effect& Entry = m_EffectCache[i];\r
1123 \r
1124         if( Entry.Location == DXUTCACHE_LOCATION_FILE &&\r
1125             !lstrcmpW( Entry.wszSource, pSrcFile ) &&\r
1126             Entry.dwFlags == Flags )\r
1127         {\r
1128             // A match is found.  Increment the ref coutn and return the ID3DXEffect object.\r
1129             *ppEffect = Entry.pEffect;\r
1130             ( *ppEffect )->AddRef();\r
1131             return S_OK;\r
1132         }\r
1133     }\r
1134 \r
1135     HRESULT hr;\r
1136 \r
1137     // No matching entry.  Load the resource and create a new entry.\r
1138     hr = D3DXCreateEffectFromFile( pDevice, pSrcFile, pDefines, pInclude, Flags, pPool, ppEffect,\r
1139                                    ppCompilationErrors );\r
1140     if( FAILED( hr ) )\r
1141         return hr;\r
1142 \r
1143     DXUTCache_Effect NewEntry;\r
1144     NewEntry.Location = DXUTCACHE_LOCATION_FILE;\r
1145     wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcFile );\r
1146     NewEntry.dwFlags = Flags;\r
1147     NewEntry.pEffect = *ppEffect;\r
1148     NewEntry.pEffect->AddRef();\r
1149 \r
1150     m_EffectCache.Add( NewEntry );\r
1151     return S_OK;\r
1152 }\r
1153 \r
1154 \r
1155 //--------------------------------------------------------------------------------------\r
1156 HRESULT CDXUTResourceCache::CreateEffectFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,\r
1157                                                       LPCTSTR pSrcResource, const D3DXMACRO* pDefines,\r
1158                                                       LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXEFFECTPOOL pPool,\r
1159                                                       LPD3DXEFFECT* ppEffect, LPD3DXBUFFER* ppCompilationErrors )\r
1160 {\r
1161     // Search the cache for a matching entry.\r
1162     for( int i = 0; i < m_EffectCache.GetSize(); ++i )\r
1163     {\r
1164         DXUTCache_Effect& Entry = m_EffectCache[i];\r
1165 \r
1166         if( Entry.Location == DXUTCACHE_LOCATION_RESOURCE &&\r
1167             Entry.hSrcModule == hSrcModule &&\r
1168             !lstrcmpW( Entry.wszSource, pSrcResource ) &&\r
1169             Entry.dwFlags == Flags )\r
1170         {\r
1171             // A match is found.  Increment the ref coutn and return the ID3DXEffect object.\r
1172             *ppEffect = Entry.pEffect;\r
1173             ( *ppEffect )->AddRef();\r
1174             return S_OK;\r
1175         }\r
1176     }\r
1177 \r
1178     HRESULT hr;\r
1179 \r
1180     // No matching entry.  Load the resource and create a new entry.\r
1181     hr = D3DXCreateEffectFromResource( pDevice, hSrcModule, pSrcResource, pDefines, pInclude, Flags,\r
1182                                        pPool, ppEffect, ppCompilationErrors );\r
1183     if( FAILED( hr ) )\r
1184         return hr;\r
1185 \r
1186     DXUTCache_Effect NewEntry;\r
1187     NewEntry.Location = DXUTCACHE_LOCATION_RESOURCE;\r
1188     NewEntry.hSrcModule = hSrcModule;\r
1189     wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcResource );\r
1190     NewEntry.dwFlags = Flags;\r
1191     NewEntry.pEffect = *ppEffect;\r
1192     NewEntry.pEffect->AddRef();\r
1193 \r
1194     m_EffectCache.Add( NewEntry );\r
1195     return S_OK;\r
1196 }\r
1197 \r
1198 \r
1199 //--------------------------------------------------------------------------------------\r
1200 // Device event callbacks\r
1201 //--------------------------------------------------------------------------------------\r
1202 \r
1203 \r
1204 //--------------------------------------------------------------------------------------\r
1205 HRESULT CDXUTResourceCache::OnCreateDevice( IDirect3DDevice9* pd3dDevice )\r
1206 {\r
1207     return S_OK;\r
1208 }\r
1209 \r
1210 \r
1211 //--------------------------------------------------------------------------------------\r
1212 HRESULT CDXUTResourceCache::OnResetDevice( IDirect3DDevice9* pd3dDevice )\r
1213 {\r
1214     // Call OnResetDevice on all effect and font objects\r
1215     for( int i = 0; i < m_EffectCache.GetSize(); ++i )\r
1216         m_EffectCache[i].pEffect->OnResetDevice();\r
1217     for( int i = 0; i < m_FontCache.GetSize(); ++i )\r
1218         m_FontCache[i].pFont->OnResetDevice();\r
1219 \r
1220 \r
1221     return S_OK;\r
1222 }\r
1223 \r
1224 \r
1225 //--------------------------------------------------------------------------------------\r
1226 HRESULT CDXUTResourceCache::OnLostDevice()\r
1227 {\r
1228     // Call OnLostDevice on all effect and font objects\r
1229     for( int i = 0; i < m_EffectCache.GetSize(); ++i )\r
1230         m_EffectCache[i].pEffect->OnLostDevice();\r
1231     for( int i = 0; i < m_FontCache.GetSize(); ++i )\r
1232         m_FontCache[i].pFont->OnLostDevice();\r
1233 \r
1234     // Release all the default pool textures\r
1235     for( int i = m_TextureCache.GetSize() - 1; i >= 0; --i )\r
1236         if( m_TextureCache[i].Pool9 == D3DPOOL_DEFAULT )\r
1237         {\r
1238             SAFE_RELEASE( m_TextureCache[i].pTexture9 );\r
1239             m_TextureCache.Remove( i );  // Remove the entry\r
1240         }\r
1241 \r
1242     return S_OK;\r
1243 }\r
1244 \r
1245 \r
1246 //--------------------------------------------------------------------------------------\r
1247 HRESULT CDXUTResourceCache::OnDestroyDevice()\r
1248 {\r
1249     // Release all resources\r
1250     for( int i = m_EffectCache.GetSize() - 1; i >= 0; --i )\r
1251     {\r
1252         SAFE_RELEASE( m_EffectCache[i].pEffect );\r
1253         m_EffectCache.Remove( i );\r
1254     }\r
1255     for( int i = m_FontCache.GetSize() - 1; i >= 0; --i )\r
1256     {\r
1257         SAFE_RELEASE( m_FontCache[i].pFont );\r
1258         m_FontCache.Remove( i );\r
1259     }\r
1260     for( int i = m_TextureCache.GetSize() - 1; i >= 0; --i )\r
1261     {\r
1262         SAFE_RELEASE( m_TextureCache[i].pTexture9 );\r
1263         SAFE_RELEASE( m_TextureCache[i].pSRV11 );\r
1264         m_TextureCache.Remove( i );\r
1265     }\r
1266 \r
1267     return S_OK;\r
1268 }\r
1269 \r
1270 \r
1271 //--------------------------------------------------------------------------------------\r
1272 // Desc: Returns a view matrix for rendering to a face of a cubemap.\r
1273 //--------------------------------------------------------------------------------------\r
1274 D3DXMATRIX WINAPI DXUTGetCubeMapViewMatrix( DWORD dwFace )\r
1275 {\r
1276     D3DXVECTOR3 vEyePt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );\r
1277     D3DXVECTOR3 vLookDir;\r
1278     D3DXVECTOR3 vUpDir;\r
1279 \r
1280     switch( dwFace )\r
1281     {\r
1282         case D3DCUBEMAP_FACE_POSITIVE_X:\r
1283             vLookDir = D3DXVECTOR3( 1.0f, 0.0f, 0.0f );\r
1284             vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );\r
1285             break;\r
1286         case D3DCUBEMAP_FACE_NEGATIVE_X:\r
1287             vLookDir = D3DXVECTOR3( -1.0f, 0.0f, 0.0f );\r
1288             vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );\r
1289             break;\r
1290         case D3DCUBEMAP_FACE_POSITIVE_Y:\r
1291             vLookDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );\r
1292             vUpDir = D3DXVECTOR3( 0.0f, 0.0f, -1.0f );\r
1293             break;\r
1294         case D3DCUBEMAP_FACE_NEGATIVE_Y:\r
1295             vLookDir = D3DXVECTOR3( 0.0f, -1.0f, 0.0f );\r
1296             vUpDir = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );\r
1297             break;\r
1298         case D3DCUBEMAP_FACE_POSITIVE_Z:\r
1299             vLookDir = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );\r
1300             vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );\r
1301             break;\r
1302         case D3DCUBEMAP_FACE_NEGATIVE_Z:\r
1303             vLookDir = D3DXVECTOR3( 0.0f, 0.0f, -1.0f );\r
1304             vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );\r
1305             break;\r
1306     }\r
1307 \r
1308     // Set the view transform for this cubemap surface\r
1309     D3DXMATRIXA16 mView;\r
1310     D3DXMatrixLookAtLH( &mView, &vEyePt, &vLookDir, &vUpDir );\r
1311     return mView;\r
1312 }\r
1313 \r
1314 \r
1315 //--------------------------------------------------------------------------------------\r
1316 CDXUTLineManager::CDXUTLineManager()\r
1317 {\r
1318     m_pd3dDevice = NULL;\r
1319     m_pD3DXLine = NULL;\r
1320 }\r
1321 \r
1322 \r
1323 //--------------------------------------------------------------------------------------\r
1324 CDXUTLineManager::~CDXUTLineManager()\r
1325 {\r
1326     OnDeletedDevice();\r
1327 }\r
1328 \r
1329 \r
1330 //--------------------------------------------------------------------------------------\r
1331 HRESULT CDXUTLineManager::OnCreatedDevice( IDirect3DDevice9* pd3dDevice )\r
1332 {\r
1333     m_pd3dDevice = pd3dDevice;\r
1334 \r
1335     HRESULT hr;\r
1336     hr = D3DXCreateLine( m_pd3dDevice, &m_pD3DXLine );\r
1337     if( FAILED( hr ) )\r
1338         return hr;\r
1339 \r
1340     return S_OK;\r
1341 }\r
1342 \r
1343 \r
1344 //--------------------------------------------------------------------------------------\r
1345 HRESULT CDXUTLineManager::OnResetDevice()\r
1346 {\r
1347     if( m_pD3DXLine )\r
1348         m_pD3DXLine->OnResetDevice();\r
1349 \r
1350     return S_OK;\r
1351 }\r
1352 \r
1353 \r
1354 //--------------------------------------------------------------------------------------\r
1355 HRESULT CDXUTLineManager::OnRender()\r
1356 {\r
1357     HRESULT hr;\r
1358     if( NULL == m_pD3DXLine )\r
1359         return E_INVALIDARG;\r
1360 \r
1361     bool bDrawingHasBegun = false;\r
1362     float fLastWidth = 0.0f;\r
1363     bool bLastAntiAlias = false;\r
1364 \r
1365     for( int i = 0; i < m_LinesList.GetSize(); i++ )\r
1366     {\r
1367         LINE_NODE* pLineNode = m_LinesList.GetAt( i );\r
1368         if( pLineNode )\r
1369         {\r
1370             if( !bDrawingHasBegun ||\r
1371                 fLastWidth != pLineNode->fWidth ||\r
1372                 bLastAntiAlias != pLineNode->bAntiAlias )\r
1373             {\r
1374                 if( bDrawingHasBegun )\r
1375                 {\r
1376                     hr = m_pD3DXLine->End();\r
1377                     if( FAILED( hr ) )\r
1378                         return hr;\r
1379                 }\r
1380 \r
1381                 m_pD3DXLine->SetWidth( pLineNode->fWidth );\r
1382                 m_pD3DXLine->SetAntialias( pLineNode->bAntiAlias );\r
1383 \r
1384                 fLastWidth = pLineNode->fWidth;\r
1385                 bLastAntiAlias = pLineNode->bAntiAlias;\r
1386 \r
1387                 hr = m_pD3DXLine->Begin();\r
1388                 if( FAILED( hr ) )\r
1389                     return hr;\r
1390                 bDrawingHasBegun = true;\r
1391             }\r
1392 \r
1393             hr = m_pD3DXLine->Draw( pLineNode->pVertexList, pLineNode->dwVertexListCount, pLineNode->Color );\r
1394             if( FAILED( hr ) )\r
1395                 return hr;\r
1396         }\r
1397     }\r
1398 \r
1399     if( bDrawingHasBegun )\r
1400     {\r
1401         hr = m_pD3DXLine->End();\r
1402         if( FAILED( hr ) )\r
1403             return hr;\r
1404     }\r
1405 \r
1406     return S_OK;\r
1407 }\r
1408 \r
1409 \r
1410 //--------------------------------------------------------------------------------------\r
1411 HRESULT CDXUTLineManager::OnLostDevice()\r
1412 {\r
1413     if( m_pD3DXLine )\r
1414         m_pD3DXLine->OnLostDevice();\r
1415 \r
1416     return S_OK;\r
1417 }\r
1418 \r
1419 \r
1420 //--------------------------------------------------------------------------------------\r
1421 HRESULT CDXUTLineManager::OnDeletedDevice()\r
1422 {\r
1423     RemoveAllLines();\r
1424     SAFE_RELEASE( m_pD3DXLine );\r
1425 \r
1426     return S_OK;\r
1427 }\r
1428 \r
1429 \r
1430 //--------------------------------------------------------------------------------------\r
1431 HRESULT CDXUTLineManager::AddLine( int* pnLineID, D3DXVECTOR2* pVertexList, DWORD dwVertexListCount, D3DCOLOR Color,\r
1432                                    float fWidth, float fScaleRatio, bool bAntiAlias )\r
1433 {\r
1434     if( pVertexList == NULL || dwVertexListCount == 0 )\r
1435         return E_INVALIDARG;\r
1436 \r
1437     LINE_NODE* pLineNode = new LINE_NODE;\r
1438     if( pLineNode == NULL )\r
1439         return E_OUTOFMEMORY;\r
1440     ZeroMemory( pLineNode, sizeof( LINE_NODE ) );\r
1441 \r
1442     pLineNode->nLineID = m_LinesList.GetSize();\r
1443     pLineNode->Color = Color;\r
1444     pLineNode->fWidth = fWidth;\r
1445     pLineNode->bAntiAlias = bAntiAlias;\r
1446     pLineNode->dwVertexListCount = dwVertexListCount;\r
1447 \r
1448     if( pnLineID )\r
1449         *pnLineID = pLineNode->nLineID;\r
1450 \r
1451     pLineNode->pVertexList = new D3DXVECTOR2[dwVertexListCount];\r
1452     if( pLineNode->pVertexList == NULL )\r
1453     {\r
1454         delete pLineNode;\r
1455         return E_OUTOFMEMORY;\r
1456     }\r
1457     for( DWORD i = 0; i < dwVertexListCount; i++ )\r
1458     {\r
1459         pLineNode->pVertexList[i] = pVertexList[i] * fScaleRatio;\r
1460     }\r
1461 \r
1462     m_LinesList.Add( pLineNode );\r
1463 \r
1464     return S_OK;\r
1465 }\r
1466 \r
1467 \r
1468 //--------------------------------------------------------------------------------------\r
1469 HRESULT CDXUTLineManager::AddRect( int* pnLineID, RECT rc, D3DCOLOR Color, float fWidth, float fScaleRatio,\r
1470                                    bool bAntiAlias )\r
1471 {\r
1472     if( fWidth > 2.0f )\r
1473     {\r
1474         D3DXVECTOR2 vertexList[8];\r
1475 \r
1476         vertexList[0].x = ( float )rc.left;\r
1477         vertexList[0].y = ( float )rc.top - ( fWidth / 2.0f );\r
1478 \r
1479         vertexList[1].x = ( float )rc.left;\r
1480         vertexList[1].y = ( float )rc.bottom + ( fWidth / 2.0f );\r
1481 \r
1482         vertexList[2].x = ( float )rc.left;\r
1483         vertexList[2].y = ( float )rc.bottom - 0.5f;\r
1484 \r
1485         vertexList[3].x = ( float )rc.right;\r
1486         vertexList[3].y = ( float )rc.bottom - 0.5f;\r
1487 \r
1488         vertexList[4].x = ( float )rc.right;\r
1489         vertexList[4].y = ( float )rc.bottom + ( fWidth / 2.0f );\r
1490 \r
1491         vertexList[5].x = ( float )rc.right;\r
1492         vertexList[5].y = ( float )rc.top - ( fWidth / 2.0f );\r
1493 \r
1494         vertexList[6].x = ( float )rc.right;\r
1495         vertexList[6].y = ( float )rc.top;\r
1496 \r
1497         vertexList[7].x = ( float )rc.left;\r
1498         vertexList[7].y = ( float )rc.top;\r
1499 \r
1500         return AddLine( pnLineID, vertexList, 8, Color, fWidth, fScaleRatio, bAntiAlias );\r
1501     }\r
1502     else\r
1503     {\r
1504         D3DXVECTOR2 vertexList[5];\r
1505         vertexList[0].x = ( float )rc.left;\r
1506         vertexList[0].y = ( float )rc.top;\r
1507 \r
1508         vertexList[1].x = ( float )rc.left;\r
1509         vertexList[1].y = ( float )rc.bottom;\r
1510 \r
1511         vertexList[2].x = ( float )rc.right;\r
1512         vertexList[2].y = ( float )rc.bottom;\r
1513 \r
1514         vertexList[3].x = ( float )rc.right;\r
1515         vertexList[3].y = ( float )rc.top;\r
1516 \r
1517         vertexList[4].x = ( float )rc.left;\r
1518         vertexList[4].y = ( float )rc.top;\r
1519 \r
1520         return AddLine( pnLineID, vertexList, 5, Color, fWidth, fScaleRatio, bAntiAlias );\r
1521     }\r
1522 }\r
1523 \r
1524 \r
1525 \r
1526 //--------------------------------------------------------------------------------------\r
1527 HRESULT CDXUTLineManager::RemoveLine( int nLineID )\r
1528 {\r
1529     for( int i = 0; i < m_LinesList.GetSize(); i++ )\r
1530     {\r
1531         LINE_NODE* pLineNode = m_LinesList.GetAt( i );\r
1532         if( pLineNode && pLineNode->nLineID == nLineID )\r
1533         {\r
1534             SAFE_DELETE_ARRAY( pLineNode->pVertexList );\r
1535             delete pLineNode;\r
1536             m_LinesList.SetAt( i, NULL );\r
1537         }\r
1538     }\r
1539 \r
1540     return S_OK;\r
1541 }\r
1542 \r
1543 \r
1544 //--------------------------------------------------------------------------------------\r
1545 HRESULT CDXUTLineManager::RemoveAllLines()\r
1546 {\r
1547     for( int i = 0; i < m_LinesList.GetSize(); i++ )\r
1548     {\r
1549         LINE_NODE* pLineNode = m_LinesList.GetAt( i );\r
1550         if( pLineNode )\r
1551         {\r
1552             SAFE_DELETE_ARRAY( pLineNode->pVertexList );\r
1553             delete pLineNode;\r
1554         }\r
1555     }\r
1556     m_LinesList.RemoveAll();\r
1557 \r
1558     return S_OK;\r
1559 }\r
1560 \r
1561 \r
1562 //--------------------------------------------------------------------------------------\r
1563 CDXUTTextHelper::CDXUTTextHelper( ID3DXFont* pFont9, ID3DXSprite* pSprite9,  int nLineHeight )\r
1564 {\r
1565     Init( pFont9, pSprite9, nLineHeight );\r
1566 }\r
1567 \r
1568 CDXUTTextHelper::CDXUTTextHelper( ID3D11Device* pd3d11Device, ID3D11DeviceContext* pd3d11DeviceContext, CDXUTDialogResourceManager* pManager, int nLineHeight )\r
1569 {\r
1570     Init( NULL, NULL, nLineHeight );\r
1571     m_pd3d11Device = pd3d11Device;\r
1572     m_pd3d11DeviceContext = pd3d11DeviceContext;\r
1573     m_pManager = pManager;\r
1574 }\r
1575 CDXUTTextHelper::~CDXUTTextHelper()\r
1576 {\r
1577 \r
1578 }\r
1579 \r
1580 //--------------------------------------------------------------------------------------\r
1581 void CDXUTTextHelper::Init( ID3DXFont* pFont9, ID3DXSprite* pSprite9, \r
1582                             int nLineHeight )\r
1583 {\r
1584     m_pFont9 = pFont9;\r
1585     m_pSprite9 = pSprite9;\r
1586     m_clr = D3DXCOLOR( 1, 1, 1, 1 );\r
1587     m_pt.x = 0;\r
1588     m_pt.y = 0;\r
1589     m_nLineHeight = nLineHeight;\r
1590     m_pd3d11Device = NULL;\r
1591     m_pd3d11DeviceContext = NULL;\r
1592     m_pManager = NULL; \r
1593 \r
1594     // Create a blend state if a sprite is passed in\r
1595 }\r
1596 \r
1597 \r
1598 //--------------------------------------------------------------------------------------\r
1599 HRESULT CDXUTTextHelper::DrawFormattedTextLine( const WCHAR* strMsg, ... )\r
1600 {\r
1601     WCHAR strBuffer[512];\r
1602 \r
1603     va_list args;\r
1604     va_start( args, strMsg );\r
1605     vswprintf_s( strBuffer, 512, strMsg, args );\r
1606     strBuffer[511] = L'\0';\r
1607     va_end( args );\r
1608 \r
1609     return DrawTextLine( strBuffer );\r
1610 }\r
1611 \r
1612 \r
1613 //--------------------------------------------------------------------------------------\r
1614 HRESULT CDXUTTextHelper::DrawTextLine( const WCHAR* strMsg )\r
1615 {\r
1616     if( NULL == m_pFont9 && NULL == m_pd3d11DeviceContext )\r
1617         return DXUT_ERR_MSGBOX( L"DrawTextLine", E_INVALIDARG );\r
1618 \r
1619     HRESULT hr = S_OK;\r
1620     RECT rc;\r
1621     SetRect( &rc, m_pt.x, m_pt.y, 0, 0 );\r
1622     if( m_pFont9 )\r
1623         hr = m_pFont9->DrawText( m_pSprite9, strMsg, -1, &rc, DT_NOCLIP, m_clr );\r
1624     else if( m_pd3d11DeviceContext )\r
1625         DrawText11DXUT( m_pd3d11Device, m_pd3d11DeviceContext, strMsg, rc, m_clr,\r
1626                         (float)m_pManager->m_nBackBufferWidth, (float)m_pManager->m_nBackBufferHeight, false );\r
1627 \r
1628     if( FAILED( hr ) )\r
1629         return DXTRACE_ERR_MSGBOX( L"DrawText", hr );\r
1630 \r
1631     m_pt.y += m_nLineHeight;\r
1632 \r
1633     return S_OK;\r
1634 }\r
1635 \r
1636 \r
1637 HRESULT CDXUTTextHelper::DrawFormattedTextLine( RECT& rc, DWORD dwFlags, const WCHAR* strMsg, ... )\r
1638 {\r
1639     WCHAR strBuffer[512];\r
1640 \r
1641     va_list args;\r
1642     va_start( args, strMsg );\r
1643     vswprintf_s( strBuffer, 512, strMsg, args );\r
1644     strBuffer[511] = L'\0';\r
1645     va_end( args );\r
1646 \r
1647     return DrawTextLine( rc, dwFlags, strBuffer );\r
1648 }\r
1649 \r
1650 \r
1651 HRESULT CDXUTTextHelper::DrawTextLine( RECT& rc, DWORD dwFlags, const WCHAR* strMsg )\r
1652 {\r
1653     if( NULL == m_pFont9 && NULL == m_pd3d11DeviceContext )\r
1654         return DXUT_ERR_MSGBOX( L"DrawTextLine", E_INVALIDARG );\r
1655 \r
1656     HRESULT hr = S_OK;\r
1657     if( m_pFont9 )\r
1658         hr = m_pFont9->DrawText( m_pSprite9, strMsg, -1, &rc, dwFlags, m_clr );\r
1659     else if( m_pd3d11DeviceContext )\r
1660         DrawText11DXUT( m_pd3d11Device, m_pd3d11DeviceContext, strMsg, rc, m_clr,\r
1661                         (float)m_pManager->m_nBackBufferWidth, (float)m_pManager->m_nBackBufferHeight, false );\r
1662 \r
1663     if( FAILED( hr ) )\r
1664         return DXTRACE_ERR_MSGBOX( L"DrawText", hr );\r
1665 \r
1666     m_pt.y += m_nLineHeight;\r
1667 \r
1668     return S_OK;\r
1669 }\r
1670 \r
1671 \r
1672 //--------------------------------------------------------------------------------------\r
1673 void CDXUTTextHelper::Begin()\r
1674 {\r
1675     if( m_pSprite9 )\r
1676         m_pSprite9->Begin( D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE );\r
1677 \r
1678     if( m_pd3d11DeviceContext )\r
1679     {\r
1680         m_pManager->StoreD3D11State( m_pd3d11DeviceContext );\r
1681         m_pManager->ApplyRenderUI11( m_pd3d11DeviceContext );\r
1682     }\r
1683 \r
1684 \r
1685 }\r
1686 void CDXUTTextHelper::End()\r
1687 {\r
1688     if( m_pSprite9 )\r
1689         m_pSprite9->End();\r
1690 \r
1691     if( m_pd3d11DeviceContext )\r
1692     {\r
1693         m_pManager->RestoreD3D11State( m_pd3d11DeviceContext );\r
1694     }\r
1695 }\r