Saxum/extern/bullet/Demos/DX11ClothDemo/DXUT/Optional/SDKmisc.cpp

1696 lines
65 KiB
C++
Raw Normal View History

2014-10-24 09:42:47 +00:00
//--------------------------------------------------------------------------------------
// File: SDKmisc.cpp
//
// Various helper functionality that is shared between SDK samples
//
// Copyright (c) Microsoft Corporation. All rights reserved
//--------------------------------------------------------------------------------------
#include "dxut.h"
#include "SDKmisc.h"
#include "DXUTres.h"
#undef min // use __min instead
#undef max // use __max instead
#include "DXUTGui.h"
//--------------------------------------------------------------------------------------
// Global/Static Members
//--------------------------------------------------------------------------------------
CDXUTResourceCache& WINAPI DXUTGetGlobalResourceCache()
{
// Using an accessor function gives control of the construction order
static CDXUTResourceCache cache;
return cache;
}
//--------------------------------------------------------------------------------------
// Internal functions forward declarations
//--------------------------------------------------------------------------------------
bool DXUTFindMediaSearchTypicalDirs( __in_ecount(cchSearch) WCHAR* strSearchPath,
int cchSearch,
__in LPCWSTR strLeaf,
__in WCHAR* strExePath,
__in WCHAR* strExeName );
bool DXUTFindMediaSearchParentDirs( __in_ecount(cchSearch) WCHAR* strSearchPath,
int cchSearch,
__in WCHAR* strStartAt,
__in WCHAR* strLeafName );
INT_PTR CALLBACK DisplaySwitchToREFWarningProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam );
//--------------------------------------------------------------------------------------
// Shared code for samples to ask user if they want to use a REF device or quit
//--------------------------------------------------------------------------------------
void WINAPI DXUTDisplaySwitchingToREFWarning( DXUTDeviceVersion ver )
{
if( DXUTGetShowMsgBoxOnError() )
{
DWORD dwSkipWarning = 0, dwRead = 0, dwWritten = 0;
HANDLE hFile = NULL;
// Read previous user settings
WCHAR strPath[MAX_PATH];
SHGetFolderPath( DXUTGetHWND(), CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, strPath );
wcscat_s( strPath, MAX_PATH, L"\\DXUT\\SkipRefWarning.dat" );
if( ( hFile = CreateFile( strPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0,
NULL ) ) != INVALID_HANDLE_VALUE )
{
ReadFile( hFile, &dwSkipWarning, sizeof( DWORD ), &dwRead, NULL );
CloseHandle( hFile );
}
if( dwSkipWarning == 0 )
{
// Compact code to create a custom dialog box without using a template in a resource file.
// If this dialog were in a .rc file, this would be a lot simpler but every sample calling this function would
// need a copy of the dialog in its own .rc file. Also MessageBox API could be used here instead, but
// the MessageBox API is simpler to call but it can't provide a "Don't show again" checkbox
typedef struct
{
DLGITEMTEMPLATE a;
WORD b;
WORD c;
WORD d;
WORD e;
WORD f;
} DXUT_DLG_ITEM;
typedef struct
{
DLGTEMPLATE a;
WORD b;
WORD c;
WCHAR d[2];
WORD e;
WCHAR f[16];
DXUT_DLG_ITEM i1;
DXUT_DLG_ITEM i2;
DXUT_DLG_ITEM i3;
DXUT_DLG_ITEM i4;
DXUT_DLG_ITEM i5;
} DXUT_DLG_DATA;
DXUT_DLG_DATA dtp =
{
{WS_CAPTION | WS_POPUP | WS_VISIBLE | WS_SYSMENU | DS_ABSALIGN | DS_3DLOOK | DS_SETFONT |
DS_MODALFRAME | DS_CENTER,0,5,0,0,269,82},0,0,L" ",8,L"MS Shell Dlg 2",
{ {WS_CHILD | WS_VISIBLE | SS_ICON | SS_CENTERIMAGE,0,7,7,24,24,0x100},0xFFFF,0x0082,0,0,0}, // icon
{ {WS_CHILD | WS_VISIBLE,0,40,7,230,25,0x101},0xFFFF,0x0082,0,0,0}, // static text
{ {WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON,0,80,39,50,14,IDYES},0xFFFF,0x0080,0,0,0}, // Yes button
{ {WS_CHILD | WS_VISIBLE | WS_TABSTOP,0,133,39,50,14,IDNO},0xFFFF,0x0080,0,0,0}, // No button
{ {WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_CHECKBOX,0,7,59,70,16,IDIGNORE},0xFFFF,0x0080,0,0,0}, // checkbox
};
LPARAM lParam;
if( ver == DXUT_D3D9_DEVICE )
lParam = 9;
else
lParam = 11;
int nResult = ( int )DialogBoxIndirectParam( DXUTGetHINSTANCE(), ( DLGTEMPLATE* )&dtp, DXUTGetHWND(),
DisplaySwitchToREFWarningProc, lParam );
if( ( nResult & 0x80 ) == 0x80 ) // "Don't show again" checkbox was checked
{
// Save user settings
dwSkipWarning = 1;
SHGetFolderPath( DXUTGetHWND(), CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, strPath );
wcscat_s( strPath, MAX_PATH, L"\\DXUT" );
CreateDirectory( strPath, NULL );
wcscat_s( strPath, MAX_PATH, L"\\SkipRefWarning.dat" );
if( ( hFile = CreateFile( strPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0,
NULL ) ) != INVALID_HANDLE_VALUE )
{
WriteFile( hFile, &dwSkipWarning, sizeof( DWORD ), &dwWritten, NULL );
CloseHandle( hFile );
}
}
// User choose not to continue
if( ( nResult & 0x0F ) == IDNO )
DXUTShutdown( 1 );
}
}
}
//--------------------------------------------------------------------------------------
// MsgProc for DXUTDisplaySwitchingToREFWarning() dialog box
//--------------------------------------------------------------------------------------
INT_PTR CALLBACK DisplaySwitchToREFWarningProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam )
{
switch( message )
{
case WM_INITDIALOG:
// Easier to set text here than in the DLGITEMTEMPLATE
SetWindowText( hDlg, DXUTGetWindowTitle() );
SendMessage( GetDlgItem( hDlg, 0x100 ), STM_SETIMAGE, IMAGE_ICON, ( LPARAM )LoadIcon( 0, IDI_QUESTION ) );
WCHAR sz[512];
swprintf_s( sz, 512,
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 );
SetDlgItemText( hDlg, 0x101, sz );
SetDlgItemText( hDlg, IDYES, L"&Yes" );
SetDlgItemText( hDlg, IDNO, L"&No" );
SetDlgItemText( hDlg, IDIGNORE, L"&Don't show again" );
break;
case WM_COMMAND:
switch( LOWORD( wParam ) )
{
case IDIGNORE:
CheckDlgButton( hDlg, IDIGNORE, ( IsDlgButtonChecked( hDlg,
IDIGNORE ) == BST_CHECKED ) ? BST_UNCHECKED :
BST_CHECKED );
EnableWindow( GetDlgItem( hDlg, IDNO ), ( IsDlgButtonChecked( hDlg, IDIGNORE ) != BST_CHECKED ) );
break;
case IDNO:
EndDialog( hDlg, ( IsDlgButtonChecked( hDlg, IDIGNORE ) == BST_CHECKED ) ? IDNO | 0x80 : IDNO |
0x00 ); return TRUE;
case IDCANCEL:
case IDYES:
EndDialog( hDlg, ( IsDlgButtonChecked( hDlg, IDIGNORE ) == BST_CHECKED ) ? IDYES | 0x80 : IDYES |
0x00 ); return TRUE;
}
break;
}
return FALSE;
}
//--------------------------------------------------------------------------------------
// Returns pointer to static media search buffer
//--------------------------------------------------------------------------------------
WCHAR* DXUTMediaSearchPath()
{
static WCHAR s_strMediaSearchPath[MAX_PATH] =
{
0
};
return s_strMediaSearchPath;
}
//--------------------------------------------------------------------------------------
LPCWSTR WINAPI DXUTGetMediaSearchPath()
{
return DXUTMediaSearchPath();
}
//--------------------------------------------------------------------------------------
HRESULT WINAPI DXUTSetMediaSearchPath( LPCWSTR strPath )
{
HRESULT hr;
WCHAR* s_strSearchPath = DXUTMediaSearchPath();
hr = wcscpy_s( s_strSearchPath, MAX_PATH, strPath );
if( SUCCEEDED( hr ) )
{
// append slash if needed
size_t ch = 0;
ch = wcsnlen( s_strSearchPath, MAX_PATH);
if( SUCCEEDED( hr ) && s_strSearchPath[ch - 1] != L'\\' )
{
hr = wcscat_s( s_strSearchPath, MAX_PATH, L"\\" );
}
}
return hr;
}
//--------------------------------------------------------------------------------------
// Tries to find the location of a SDK media file
// cchDest is the size in WCHARs of strDestPath. Be careful not to
// pass in sizeof(strDest) on UNICODE builds.
//--------------------------------------------------------------------------------------
HRESULT WINAPI DXUTFindDXSDKMediaFileCch(__in_ecount(cchDest) WCHAR* strDestPath,
int cchDest,
__in LPCWSTR strFilename )
{
bool bFound;
WCHAR strSearchFor[MAX_PATH];
if( NULL == strFilename || strFilename[0] == 0 || NULL == strDestPath || cchDest < 10 )
return E_INVALIDARG;
// Get the exe name, and exe path
WCHAR strExePath[MAX_PATH] =
{
0
};
WCHAR strExeName[MAX_PATH] =
{
0
};
WCHAR* strLastSlash = NULL;
GetModuleFileName( NULL, strExePath, MAX_PATH );
strExePath[MAX_PATH - 1] = 0;
strLastSlash = wcsrchr( strExePath, TEXT( '\\' ) );
if( strLastSlash )
{
wcscpy_s( strExeName, MAX_PATH, &strLastSlash[1] );
// Chop the exe name from the exe path
*strLastSlash = 0;
// Chop the .exe from the exe name
strLastSlash = wcsrchr( strExeName, TEXT( '.' ) );
if( strLastSlash )
*strLastSlash = 0;
}
// Typical directories:
// .\
// ..\
// ..\..\
// %EXE_DIR%\
// %EXE_DIR%\..\
// %EXE_DIR%\..\..\
// %EXE_DIR%\..\%EXE_NAME%
// %EXE_DIR%\..\..\%EXE_NAME%
// Typical directory search
bFound = DXUTFindMediaSearchTypicalDirs( strDestPath, cchDest, strFilename, strExePath, strExeName );
if( bFound )
return S_OK;
// Typical directory search again, but also look in a subdir called "\media\"
swprintf_s( strSearchFor, MAX_PATH, L"media\\%s", strFilename );
bFound = DXUTFindMediaSearchTypicalDirs( strDestPath, cchDest, strSearchFor, strExePath, strExeName );
if( bFound )
return S_OK;
WCHAR strLeafName[MAX_PATH] =
{
0
};
// Search all parent directories starting at .\ and using strFilename as the leaf name
wcscpy_s( strLeafName, MAX_PATH, strFilename );
bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, L".", strLeafName );
if( bFound )
return S_OK;
// Search all parent directories starting at the exe's dir and using strFilename as the leaf name
bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, strExePath, strLeafName );
if( bFound )
return S_OK;
// Search all parent directories starting at .\ and using "media\strFilename" as the leaf name
swprintf_s( strLeafName, MAX_PATH, L"media\\%s", strFilename );
bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, L".", strLeafName );
if( bFound )
return S_OK;
// Search all parent directories starting at the exe's dir and using "media\strFilename" as the leaf name
bFound = DXUTFindMediaSearchParentDirs( strDestPath, cchDest, strExePath, strLeafName );
if( bFound )
return S_OK;
// On failure, return the file as the path but also return an error code
wcscpy_s( strDestPath, cchDest, strFilename );
return DXUTERR_MEDIANOTFOUND;
}
//--------------------------------------------------------------------------------------
// Search a set of typical directories
//--------------------------------------------------------------------------------------
bool DXUTFindMediaSearchTypicalDirs( __in_ecount(cchSearch) WCHAR* strSearchPath,
int cchSearch,
__in LPCWSTR strLeaf,
__in WCHAR* strExePath,
__in WCHAR* strExeName )
{
// Typical directories:
// .\
// ..\
// ..\..\
// %EXE_DIR%\
// %EXE_DIR%\..\
// %EXE_DIR%\..\..\
// %EXE_DIR%\..\%EXE_NAME%
// %EXE_DIR%\..\..\%EXE_NAME%
// DXSDK media path
// Search in .\
wcscpy_s( strSearchPath, cchSearch, strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in ..\
swprintf_s( strSearchPath, cchSearch, L"..\\%s", strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in ..\..\
swprintf_s( strSearchPath, cchSearch, L"..\\..\\%s", strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in ..\..\
swprintf_s( strSearchPath, cchSearch, L"..\\..\\%s", strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in the %EXE_DIR%\
swprintf_s( strSearchPath, cchSearch, L"%s\\%s", strExePath, strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in the %EXE_DIR%\..\
swprintf_s( strSearchPath, cchSearch, L"%s\\..\\%s", strExePath, strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in the %EXE_DIR%\..\..\
swprintf_s( strSearchPath, cchSearch, L"%s\\..\\..\\%s", strExePath, strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in "%EXE_DIR%\..\%EXE_NAME%\". This matches the DirectX SDK layout
swprintf_s( strSearchPath, cchSearch, L"%s\\..\\%s\\%s", strExePath, strExeName, strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in "%EXE_DIR%\..\..\%EXE_NAME%\". This matches the DirectX SDK layout
swprintf_s( strSearchPath, cchSearch, L"%s\\..\\..\\%s\\%s", strExePath, strExeName, strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in "%EXE_DIR%\Demos\DX11ClothDemo\Media\". This matches the Bullet SDK layout
swprintf_s( strSearchPath, cchSearch, L"%s\\Demos\\DX11ClothDemo\\Media\\%s", strExePath, strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in "%EXE_DIR%\Demos\DX11ClothDemo\". This matches the Bullet SDK layout
swprintf_s( strSearchPath, cchSearch, L"%s\\Demos\\DX11ClothDemo\\%s", strExePath, strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
// Search in media search dir
WCHAR* s_strSearchPath = DXUTMediaSearchPath();
if( s_strSearchPath[0] != 0 )
{
swprintf_s( strSearchPath, cchSearch, L"%s%s", s_strSearchPath, strLeaf );
if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
return true;
}
return false;
}
//--------------------------------------------------------------------------------------
// Search parent directories starting at strStartAt, and appending strLeafName
// at each parent directory. It stops at the root directory.
//--------------------------------------------------------------------------------------
bool DXUTFindMediaSearchParentDirs( __in_ecount(cchSearch) WCHAR* strSearchPath,
int cchSearch,
__in WCHAR* strStartAt,
__in WCHAR* strLeafName )
{
WCHAR strFullPath[MAX_PATH] =
{
0
};
WCHAR strFullFileName[MAX_PATH] =
{
0
};
WCHAR strSearch[MAX_PATH] =
{
0
};
WCHAR* strFilePart = NULL;
GetFullPathName( strStartAt, MAX_PATH, strFullPath, &strFilePart );
if( strFilePart == NULL )
return false;
while( strFilePart != NULL && *strFilePart != '\0' )
{
swprintf_s( strFullFileName, MAX_PATH, L"%s\\%s", strFullPath, strLeafName );
if( GetFileAttributes( strFullFileName ) != 0xFFFFFFFF )
{
wcscpy_s( strSearchPath, cchSearch, strFullFileName );
return true;
}
swprintf_s( strSearch, MAX_PATH, L"%s\\..", strFullPath );
GetFullPathName( strSearch, MAX_PATH, strFullPath, &strFilePart );
}
return false;
}
//--------------------------------------------------------------------------------------
// CDXUTResourceCache
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
CDXUTResourceCache::~CDXUTResourceCache()
{
OnDestroyDevice();
m_TextureCache.RemoveAll();
m_EffectCache.RemoveAll();
m_FontCache.RemoveAll();
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile,
LPDIRECT3DTEXTURE9* ppTexture )
{
return CreateTextureFromFileEx( pDevice, pSrcFile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
0, NULL, NULL, ppTexture );
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCSTR pSrcFile,
LPDIRECT3DTEXTURE9* ppTexture )
{
WCHAR szSrcFile[MAX_PATH];
MultiByteToWideChar( CP_ACP, 0, pSrcFile, -1, szSrcFile, MAX_PATH );
szSrcFile[MAX_PATH - 1] = 0;
return CreateTextureFromFile( pDevice, szSrcFile, ppTexture );
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateTextureFromFile( ID3D11Device* pDevice, ID3D11DeviceContext *pContext, LPCTSTR pSrcFile,
ID3D11ShaderResourceView** ppOutputRV, bool bSRGB )
{
return CreateTextureFromFileEx( pDevice, pContext, pSrcFile, NULL, NULL, ppOutputRV, bSRGB );
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateTextureFromFile( ID3D11Device* pDevice, ID3D11DeviceContext *pContext, LPCSTR pSrcFile,
ID3D11ShaderResourceView** ppOutputRV, bool bSRGB )
{
WCHAR szSrcFile[MAX_PATH];
MultiByteToWideChar( CP_ACP, 0, pSrcFile, -1, szSrcFile, MAX_PATH );
szSrcFile[MAX_PATH - 1] = 0;
return CreateTextureFromFile( pDevice, pContext, szSrcFile, ppOutputRV, bSRGB );
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Width,
UINT Height, UINT MipLevels, DWORD Usage, D3DFORMAT Format,
D3DPOOL Pool, DWORD Filter, DWORD MipFilter, D3DCOLOR ColorKey,
D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette,
LPDIRECT3DTEXTURE9* ppTexture )
{
// Search the cache for a matching entry.
for( int i = 0; i < m_TextureCache.GetSize(); ++i )
{
DXUTCache_Texture& Entry = m_TextureCache[i];
if( Entry.Location == DXUTCACHE_LOCATION_FILE &&
!lstrcmpW( Entry.wszSource, pSrcFile ) &&
Entry.Width == Width &&
Entry.Height == Height &&
Entry.MipLevels == MipLevels &&
Entry.Usage9 == Usage &&
Entry.Format9 == Format &&
Entry.Pool9 == Pool &&
Entry.Type9 == D3DRTYPE_TEXTURE )
{
// A match is found. Obtain the IDirect3DTexture9 interface and return that.
return Entry.pTexture9->QueryInterface( IID_IDirect3DTexture9, ( LPVOID* )ppTexture );
}
}
HRESULT hr;
// No matching entry. Load the resource and create a new entry.
hr = D3DXCreateTextureFromFileEx( pDevice, pSrcFile, Width, Height, MipLevels, Usage, Format,
Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette, ppTexture );
if( FAILED( hr ) )
return hr;
DXUTCache_Texture NewEntry;
NewEntry.Location = DXUTCACHE_LOCATION_FILE;
wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcFile );
NewEntry.Width = Width;
NewEntry.Height = Height;
NewEntry.MipLevels = MipLevels;
NewEntry.Usage9 = Usage;
NewEntry.Format9 = Format;
NewEntry.Pool9 = Pool;
NewEntry.Type9 = D3DRTYPE_TEXTURE;
( *ppTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 );
m_TextureCache.Add( NewEntry );
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateTextureFromFileEx( ID3D11Device* pDevice, ID3D11DeviceContext* pContext, LPCTSTR pSrcFile,
D3DX11_IMAGE_LOAD_INFO* pLoadInfo, ID3DX11ThreadPump* pPump,
ID3D11ShaderResourceView** ppOutputRV, bool bSRGB )
{
bool is10L9 = DXUTGetDeviceSettings().d3d11.DeviceFeatureLevel < D3D_FEATURE_LEVEL_10_0;
HRESULT hr = S_OK;
D3DX11_IMAGE_LOAD_INFO ZeroInfo; //D3DX11_IMAGE_LOAD_INFO has a default constructor
D3DX11_IMAGE_INFO SrcInfo;
if( !pLoadInfo )
{
pLoadInfo = &ZeroInfo;
}
if( !pLoadInfo->pSrcInfo )
{
D3DX11GetImageInfoFromFile( pSrcFile, NULL, &SrcInfo, NULL );
pLoadInfo->pSrcInfo = &SrcInfo;
pLoadInfo->Format = pLoadInfo->pSrcInfo->Format;
}
// Search the cache for a matching entry.
for( int i = 0; i < m_TextureCache.GetSize(); ++i )
{
DXUTCache_Texture& Entry = m_TextureCache[i];
if( Entry.Location == DXUTCACHE_LOCATION_FILE &&
!lstrcmpW( Entry.wszSource, pSrcFile ) &&
Entry.Width == pLoadInfo->Width &&
Entry.Height == pLoadInfo->Height &&
Entry.MipLevels == pLoadInfo->MipLevels &&
Entry.Usage11 == pLoadInfo->Usage &&
Entry.Format == pLoadInfo->Format &&
Entry.CpuAccessFlags == pLoadInfo->CpuAccessFlags &&
Entry.BindFlags == pLoadInfo->BindFlags &&
Entry.MiscFlags == pLoadInfo->MiscFlags )
{
// A match is found. Obtain the IDirect3DTexture9 interface and return that.
return Entry.pSRV11->QueryInterface( __uuidof( ID3D11ShaderResourceView ), ( LPVOID* )ppOutputRV );
}
}
//Ready a new entry to the texture cache
//Do this before creating the texture since pLoadInfo may be volatile
DXUTCache_Texture NewEntry;
NewEntry.Location = DXUTCACHE_LOCATION_FILE;
wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcFile );
NewEntry.Width = pLoadInfo->Width;
NewEntry.Height = pLoadInfo->Height;
NewEntry.MipLevels = pLoadInfo->MipLevels;
NewEntry.Usage11 = pLoadInfo->Usage;
// 10L9 can't handle typesless, so we cant make a typesless format
if (is10L9 && bSRGB) {
NewEntry.Format = MAKE_SRGB(pLoadInfo->Format);
}else {
NewEntry.Format = pLoadInfo->Format;
}
NewEntry.CpuAccessFlags = pLoadInfo->CpuAccessFlags;
NewEntry.BindFlags = pLoadInfo->BindFlags;
NewEntry.MiscFlags = pLoadInfo->MiscFlags;
//Create the rexture
ID3D11Texture2D* pRes = NULL;
hr = D3DX11CreateTextureFromFile( pDevice, pSrcFile, pLoadInfo, pPump, ( ID3D11Resource** )&pRes, NULL );
if( FAILED( hr ) )
return hr;
D3D11_TEXTURE2D_DESC tex_dsc;
pRes->GetDesc(&tex_dsc);
if (bSRGB ) {
// This is a workaround so that we can load linearly, but sample in SRGB. Right now, we can't load
// as linear since D3DX will try to do conversion on load. Loading as TYPELESS doesn't work either, and
// loading as typed _UNORM doesn't allow us to create an SRGB view.
// on d3d11 featuer levels this is just a copy, but on 10L9 we must use a cpu side copy with 2 staging resources.
ID3D11Texture2D* unormStaging = NULL;
ID3D11Texture2D* srgbStaging = NULL;
D3D11_TEXTURE2D_DESC CopyDesc;
pRes->GetDesc( &CopyDesc );
pLoadInfo->BindFlags = 0;
pLoadInfo->CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
pLoadInfo->Depth = 0;
pLoadInfo->Filter = D3DX11_FILTER_POINT;
pLoadInfo->FirstMipLevel = 0;
pLoadInfo->Format = CopyDesc.Format;
pLoadInfo->Height = CopyDesc.Height;
pLoadInfo->MipFilter = D3DX11_FILTER_POINT;
pLoadInfo->MiscFlags = CopyDesc.MiscFlags;
pLoadInfo->Usage = D3D11_USAGE_STAGING;
pLoadInfo->Width = CopyDesc.Width;
CopyDesc.BindFlags = 0;
CopyDesc.Usage = D3D11_USAGE_STAGING;
CopyDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
CopyDesc.Format = MAKE_SRGB(CopyDesc.Format);
hr = D3DX11CreateTextureFromFile( pDevice, pSrcFile, pLoadInfo, pPump, ( ID3D11Resource** )&unormStaging, NULL );
hr = pDevice->CreateTexture2D(&CopyDesc, NULL, &srgbStaging);
pContext->CopyResource( srgbStaging, unormStaging );
ID3D11Texture2D* srgbGPU;
pRes->GetDesc( &CopyDesc );
CopyDesc.Format = MAKE_SRGB(CopyDesc.Format);
hr = pDevice->CreateTexture2D(&CopyDesc, NULL, &srgbGPU);
pContext->CopyResource( srgbGPU, srgbStaging );
SAFE_RELEASE(pRes);
SAFE_RELEASE(srgbStaging);
SAFE_RELEASE(unormStaging);
pRes = srgbGPU;
}
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
if( bSRGB )
SRVDesc.Format = MAKE_SRGB( ZeroInfo.Format );
else
SRVDesc.Format = ZeroInfo.Format;
if( pLoadInfo->pSrcInfo->ResourceDimension == D3D11_RESOURCE_DIMENSION_TEXTURE1D )
{
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
SRVDesc.Texture1D.MostDetailedMip = 0;
SRVDesc.Texture1D.MipLevels = pLoadInfo->pSrcInfo->MipLevels;
}
else if( pLoadInfo->pSrcInfo->ResourceDimension == D3D11_RESOURCE_DIMENSION_TEXTURE2D )
{
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
SRVDesc.Texture2D.MostDetailedMip = 0;
SRVDesc.Texture2D.MipLevels = pLoadInfo->pSrcInfo->MipLevels;
if( pLoadInfo->pSrcInfo->MiscFlags & D3D11_RESOURCE_MISC_TEXTURECUBE )
{
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
SRVDesc.TextureCube.MostDetailedMip = 0;
SRVDesc.TextureCube.MipLevels = pLoadInfo->pSrcInfo->MipLevels;
}
}
else if( pLoadInfo->pSrcInfo->ResourceDimension == D3D11_RESOURCE_DIMENSION_TEXTURE3D )
{
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
SRVDesc.Texture3D.MostDetailedMip = 0;
SRVDesc.Texture3D.MipLevels = pLoadInfo->pSrcInfo->MipLevels;
}
if (bSRGB) {
SRVDesc.Format = MAKE_SRGB(tex_dsc.Format);
}else {
SRVDesc.Format = tex_dsc.Format;
}
SRVDesc.Texture2D.MipLevels = tex_dsc.MipLevels;
SRVDesc.Texture2D.MostDetailedMip = 0;
hr = pDevice->CreateShaderResourceView( pRes, &SRVDesc, ppOutputRV );
pRes->Release();
if( FAILED( hr ) )
return hr;
( *ppOutputRV )->QueryInterface( __uuidof( ID3D11ShaderResourceView ), ( LPVOID* )&NewEntry.pSRV11 );
m_TextureCache.Add( NewEntry );
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,
LPCTSTR pSrcResource, LPDIRECT3DTEXTURE9* ppTexture )
{
return CreateTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, D3DX_DEFAULT, D3DX_DEFAULT,
D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT,
D3DX_DEFAULT, 0, NULL, NULL, ppTexture );
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateTextureFromResourceEx( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,
LPCTSTR pSrcResource, UINT Width, UINT Height, UINT MipLevels,
DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, DWORD Filter,
DWORD MipFilter, D3DCOLOR ColorKey, D3DXIMAGE_INFO* pSrcInfo,
PALETTEENTRY* pPalette, LPDIRECT3DTEXTURE9* ppTexture )
{
// Search the cache for a matching entry.
for( int i = 0; i < m_TextureCache.GetSize(); ++i )
{
DXUTCache_Texture& Entry = m_TextureCache[i];
if( Entry.Location == DXUTCACHE_LOCATION_RESOURCE &&
Entry.hSrcModule == hSrcModule &&
!lstrcmpW( Entry.wszSource, pSrcResource ) &&
Entry.Width == Width &&
Entry.Height == Height &&
Entry.MipLevels == MipLevels &&
Entry.Usage9 == Usage &&
Entry.Format9 == Format &&
Entry.Pool9 == Pool &&
Entry.Type9 == D3DRTYPE_TEXTURE )
{
// A match is found. Obtain the IDirect3DTexture9 interface and return that.
return Entry.pTexture9->QueryInterface( IID_IDirect3DTexture9, ( LPVOID* )ppTexture );
}
}
HRESULT hr;
// No matching entry. Load the resource and create a new entry.
hr = D3DXCreateTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, Width, Height, MipLevels, Usage,
Format, Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette, ppTexture );
if( FAILED( hr ) )
return hr;
DXUTCache_Texture NewEntry;
NewEntry.Location = DXUTCACHE_LOCATION_RESOURCE;
NewEntry.hSrcModule = hSrcModule;
wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcResource );
NewEntry.Width = Width;
NewEntry.Height = Height;
NewEntry.MipLevels = MipLevels;
NewEntry.Usage9 = Usage;
NewEntry.Format9 = Format;
NewEntry.Pool9 = Pool;
NewEntry.Type9 = D3DRTYPE_TEXTURE;
( *ppTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 );
m_TextureCache.Add( NewEntry );
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateCubeTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile,
LPDIRECT3DCUBETEXTURE9* ppCubeTexture )
{
return CreateCubeTextureFromFileEx( pDevice, pSrcFile, D3DX_DEFAULT, D3DX_DEFAULT, 0,
D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
0, NULL, NULL, ppCubeTexture );
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateCubeTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Size,
UINT MipLevels, DWORD Usage, D3DFORMAT Format, D3DPOOL Pool,
DWORD Filter, DWORD MipFilter, D3DCOLOR ColorKey,
D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette,
LPDIRECT3DCUBETEXTURE9* ppCubeTexture )
{
// Search the cache for a matching entry.
for( int i = 0; i < m_TextureCache.GetSize(); ++i )
{
DXUTCache_Texture& Entry = m_TextureCache[i];
if( Entry.Location == DXUTCACHE_LOCATION_FILE &&
!lstrcmpW( Entry.wszSource, pSrcFile ) &&
Entry.Width == Size &&
Entry.MipLevels == MipLevels &&
Entry.Usage9 == Usage &&
Entry.Format9 == Format &&
Entry.Pool9 == Pool &&
Entry.Type9 == D3DRTYPE_CUBETEXTURE )
{
// A match is found. Obtain the IDirect3DCubeTexture9 interface and return that.
return Entry.pTexture9->QueryInterface( IID_IDirect3DCubeTexture9, ( LPVOID* )ppCubeTexture );
}
}
HRESULT hr;
// No matching entry. Load the resource and create a new entry.
hr = D3DXCreateCubeTextureFromFileEx( pDevice, pSrcFile, Size, MipLevels, Usage, Format, Pool, Filter,
MipFilter, ColorKey, pSrcInfo, pPalette, ppCubeTexture );
if( FAILED( hr ) )
return hr;
DXUTCache_Texture NewEntry;
NewEntry.Location = DXUTCACHE_LOCATION_FILE;
wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcFile );
NewEntry.Width = Size;
NewEntry.MipLevels = MipLevels;
NewEntry.Usage9 = Usage;
NewEntry.Format9 = Format;
NewEntry.Pool9 = Pool;
NewEntry.Type9 = D3DRTYPE_CUBETEXTURE;
( *ppCubeTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 );
m_TextureCache.Add( NewEntry );
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateCubeTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,
LPCTSTR pSrcResource,
LPDIRECT3DCUBETEXTURE9* ppCubeTexture )
{
return CreateCubeTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, D3DX_DEFAULT, D3DX_DEFAULT,
0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
0, NULL, NULL, ppCubeTexture );
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateCubeTextureFromResourceEx( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,
LPCTSTR pSrcResource, UINT Size, UINT MipLevels,
DWORD Usage, D3DFORMAT Format, D3DPOOL Pool, DWORD Filter,
DWORD MipFilter, D3DCOLOR ColorKey,
D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette,
LPDIRECT3DCUBETEXTURE9* ppCubeTexture )
{
// Search the cache for a matching entry.
for( int i = 0; i < m_TextureCache.GetSize(); ++i )
{
DXUTCache_Texture& Entry = m_TextureCache[i];
if( Entry.Location == DXUTCACHE_LOCATION_RESOURCE &&
Entry.hSrcModule == hSrcModule &&
!lstrcmpW( Entry.wszSource, pSrcResource ) &&
Entry.Width == Size &&
Entry.MipLevels == MipLevels &&
Entry.Usage9 == Usage &&
Entry.Format9 == Format &&
Entry.Pool9 == Pool &&
Entry.Type9 == D3DRTYPE_CUBETEXTURE )
{
// A match is found. Obtain the IDirect3DCubeTexture9 interface and return that.
return Entry.pTexture9->QueryInterface( IID_IDirect3DCubeTexture9, ( LPVOID* )ppCubeTexture );
}
}
HRESULT hr;
// No matching entry. Load the resource and create a new entry.
hr = D3DXCreateCubeTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, Size, MipLevels, Usage, Format,
Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette, ppCubeTexture );
if( FAILED( hr ) )
return hr;
DXUTCache_Texture NewEntry;
NewEntry.Location = DXUTCACHE_LOCATION_RESOURCE;
NewEntry.hSrcModule = hSrcModule;
wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcResource );
NewEntry.Width = Size;
NewEntry.MipLevels = MipLevels;
NewEntry.Usage9 = Usage;
NewEntry.Format9 = Format;
NewEntry.Pool9 = Pool;
NewEntry.Type9 = D3DRTYPE_CUBETEXTURE;
( *ppCubeTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 );
m_TextureCache.Add( NewEntry );
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateVolumeTextureFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile,
LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture )
{
return CreateVolumeTextureFromFileEx( pDevice, pSrcFile, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT,
0, NULL, NULL, ppVolumeTexture );
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateVolumeTextureFromFileEx( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile, UINT Width,
UINT Height, UINT Depth, UINT MipLevels, DWORD Usage,
D3DFORMAT Format, D3DPOOL Pool, DWORD Filter,
DWORD MipFilter, D3DCOLOR ColorKey,
D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette,
LPDIRECT3DVOLUMETEXTURE9* ppTexture )
{
// Search the cache for a matching entry.
for( int i = 0; i < m_TextureCache.GetSize(); ++i )
{
DXUTCache_Texture& Entry = m_TextureCache[i];
if( Entry.Location == DXUTCACHE_LOCATION_FILE &&
!lstrcmpW( Entry.wszSource, pSrcFile ) &&
Entry.Width == Width &&
Entry.Height == Height &&
Entry.Depth == Depth &&
Entry.MipLevels == MipLevels &&
Entry.Usage9 == Usage &&
Entry.Format9 == Format &&
Entry.Pool9 == Pool &&
Entry.Type9 == D3DRTYPE_VOLUMETEXTURE )
{
// A match is found. Obtain the IDirect3DVolumeTexture9 interface and return that.
return Entry.pTexture9->QueryInterface( IID_IDirect3DVolumeTexture9, ( LPVOID* )ppTexture );
}
}
HRESULT hr;
// No matching entry. Load the resource and create a new entry.
hr = D3DXCreateVolumeTextureFromFileEx( pDevice, pSrcFile, Width, Height, Depth, MipLevels, Usage, Format,
Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette, ppTexture );
if( FAILED( hr ) )
return hr;
DXUTCache_Texture NewEntry;
NewEntry.Location = DXUTCACHE_LOCATION_FILE;
wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcFile );
NewEntry.Width = Width;
NewEntry.Height = Height;
NewEntry.Depth = Depth;
NewEntry.MipLevels = MipLevels;
NewEntry.Usage9 = Usage;
NewEntry.Format9 = Format;
NewEntry.Pool9 = Pool;
NewEntry.Type9 = D3DRTYPE_VOLUMETEXTURE;
( *ppTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 );
m_TextureCache.Add( NewEntry );
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateVolumeTextureFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,
LPCTSTR pSrcResource,
LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture )
{
return CreateVolumeTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, D3DX_DEFAULT, D3DX_DEFAULT,
D3DX_DEFAULT, D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED,
D3DX_DEFAULT, D3DX_DEFAULT, 0, NULL, NULL, ppVolumeTexture );
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateVolumeTextureFromResourceEx( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,
LPCTSTR pSrcResource, UINT Width, UINT Height,
UINT Depth, UINT MipLevels, DWORD Usage,
D3DFORMAT Format, D3DPOOL Pool, DWORD Filter,
DWORD MipFilter, D3DCOLOR ColorKey,
D3DXIMAGE_INFO* pSrcInfo, PALETTEENTRY* pPalette,
LPDIRECT3DVOLUMETEXTURE9* ppVolumeTexture )
{
// Search the cache for a matching entry.
for( int i = 0; i < m_TextureCache.GetSize(); ++i )
{
DXUTCache_Texture& Entry = m_TextureCache[i];
if( Entry.Location == DXUTCACHE_LOCATION_RESOURCE &&
Entry.hSrcModule == hSrcModule &&
!lstrcmpW( Entry.wszSource, pSrcResource ) &&
Entry.Width == Width &&
Entry.Height == Height &&
Entry.Depth == Depth &&
Entry.MipLevels == MipLevels &&
Entry.Usage9 == Usage &&
Entry.Format9 == Format &&
Entry.Pool9 == Pool &&
Entry.Type9 == D3DRTYPE_VOLUMETEXTURE )
{
// A match is found. Obtain the IDirect3DVolumeTexture9 interface and return that.
return Entry.pTexture9->QueryInterface( IID_IDirect3DVolumeTexture9, ( LPVOID* )ppVolumeTexture );
}
}
HRESULT hr;
// No matching entry. Load the resource and create a new entry.
hr = D3DXCreateVolumeTextureFromResourceEx( pDevice, hSrcModule, pSrcResource, Width, Height, Depth, MipLevels,
Usage,
Format, Pool, Filter, MipFilter, ColorKey, pSrcInfo, pPalette,
ppVolumeTexture );
if( FAILED( hr ) )
return hr;
DXUTCache_Texture NewEntry;
NewEntry.Location = DXUTCACHE_LOCATION_RESOURCE;
NewEntry.hSrcModule = hSrcModule;
wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcResource );
NewEntry.Width = Width;
NewEntry.Height = Height;
NewEntry.Depth = Depth;
NewEntry.MipLevels = MipLevels;
NewEntry.Usage9 = Usage;
NewEntry.Format9 = Format;
NewEntry.Pool9 = Pool;
NewEntry.Type9 = D3DRTYPE_VOLUMETEXTURE;
( *ppVolumeTexture )->QueryInterface( IID_IDirect3DBaseTexture9, ( LPVOID* )&NewEntry.pTexture9 );
m_TextureCache.Add( NewEntry );
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateFont( LPDIRECT3DDEVICE9 pDevice, UINT Height, UINT Width, UINT Weight,
UINT MipLevels, BOOL Italic, DWORD CharSet, DWORD OutputPrecision,
DWORD Quality, DWORD PitchAndFamily, LPCTSTR pFacename, LPD3DXFONT* ppFont )
{
D3DXFONT_DESCW Desc;
Desc.Height = Height;
Desc.Width = Width;
Desc.Weight = Weight;
Desc.MipLevels = MipLevels;
Desc.Italic = Italic;
Desc.CharSet = ( BYTE )CharSet;
Desc.OutputPrecision = ( BYTE )OutputPrecision;
Desc.Quality = ( BYTE )Quality;
Desc.PitchAndFamily = ( BYTE )PitchAndFamily;
wcscpy_s( Desc.FaceName, LF_FACESIZE, pFacename );
return CreateFontIndirect( pDevice, &Desc, ppFont );
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateFontIndirect( LPDIRECT3DDEVICE9 pDevice, CONST D3DXFONT_DESC *pDesc, LPD3DXFONT *ppFont )
{
// Search the cache for a matching entry.
for( int i = 0; i < m_FontCache.GetSize(); ++i )
{
DXUTCache_Font &Entry = m_FontCache[i];
if( Entry.Width == pDesc->Width &&
Entry.Height == pDesc->Height &&
Entry.Weight == pDesc->Weight &&
Entry.MipLevels == pDesc->MipLevels &&
Entry.Italic == pDesc->Italic &&
Entry.CharSet == pDesc->CharSet &&
Entry.OutputPrecision == pDesc->OutputPrecision &&
Entry.Quality == pDesc->Quality &&
Entry.PitchAndFamily == pDesc->PitchAndFamily &&
CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE,
Entry.FaceName, -1,
pDesc->FaceName, -1 ) == CSTR_EQUAL )
{
// A match is found. Increment the reference and return the ID3DXFont object.
Entry.pFont->AddRef();
*ppFont = Entry.pFont;
return S_OK;
}
}
HRESULT hr;
// No matching entry. Load the resource and create a new entry.
hr = D3DXCreateFontIndirect( pDevice, pDesc, ppFont );
if( FAILED( hr ) )
return hr;
DXUTCache_Font NewEntry;
( D3DXFONT_DESC & )NewEntry = *pDesc;
NewEntry.pFont = *ppFont;
NewEntry.pFont->AddRef();
m_FontCache.Add( NewEntry );
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateEffectFromFile( LPDIRECT3DDEVICE9 pDevice, LPCTSTR pSrcFile,
const D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, DWORD Flags,
LPD3DXEFFECTPOOL pPool, LPD3DXEFFECT* ppEffect,
LPD3DXBUFFER* ppCompilationErrors )
{
// Search the cache for a matching entry.
for( int i = 0; i < m_EffectCache.GetSize(); ++i )
{
DXUTCache_Effect& Entry = m_EffectCache[i];
if( Entry.Location == DXUTCACHE_LOCATION_FILE &&
!lstrcmpW( Entry.wszSource, pSrcFile ) &&
Entry.dwFlags == Flags )
{
// A match is found. Increment the ref coutn and return the ID3DXEffect object.
*ppEffect = Entry.pEffect;
( *ppEffect )->AddRef();
return S_OK;
}
}
HRESULT hr;
// No matching entry. Load the resource and create a new entry.
hr = D3DXCreateEffectFromFile( pDevice, pSrcFile, pDefines, pInclude, Flags, pPool, ppEffect,
ppCompilationErrors );
if( FAILED( hr ) )
return hr;
DXUTCache_Effect NewEntry;
NewEntry.Location = DXUTCACHE_LOCATION_FILE;
wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcFile );
NewEntry.dwFlags = Flags;
NewEntry.pEffect = *ppEffect;
NewEntry.pEffect->AddRef();
m_EffectCache.Add( NewEntry );
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::CreateEffectFromResource( LPDIRECT3DDEVICE9 pDevice, HMODULE hSrcModule,
LPCTSTR pSrcResource, const D3DXMACRO* pDefines,
LPD3DXINCLUDE pInclude, DWORD Flags, LPD3DXEFFECTPOOL pPool,
LPD3DXEFFECT* ppEffect, LPD3DXBUFFER* ppCompilationErrors )
{
// Search the cache for a matching entry.
for( int i = 0; i < m_EffectCache.GetSize(); ++i )
{
DXUTCache_Effect& Entry = m_EffectCache[i];
if( Entry.Location == DXUTCACHE_LOCATION_RESOURCE &&
Entry.hSrcModule == hSrcModule &&
!lstrcmpW( Entry.wszSource, pSrcResource ) &&
Entry.dwFlags == Flags )
{
// A match is found. Increment the ref coutn and return the ID3DXEffect object.
*ppEffect = Entry.pEffect;
( *ppEffect )->AddRef();
return S_OK;
}
}
HRESULT hr;
// No matching entry. Load the resource and create a new entry.
hr = D3DXCreateEffectFromResource( pDevice, hSrcModule, pSrcResource, pDefines, pInclude, Flags,
pPool, ppEffect, ppCompilationErrors );
if( FAILED( hr ) )
return hr;
DXUTCache_Effect NewEntry;
NewEntry.Location = DXUTCACHE_LOCATION_RESOURCE;
NewEntry.hSrcModule = hSrcModule;
wcscpy_s( NewEntry.wszSource, MAX_PATH, pSrcResource );
NewEntry.dwFlags = Flags;
NewEntry.pEffect = *ppEffect;
NewEntry.pEffect->AddRef();
m_EffectCache.Add( NewEntry );
return S_OK;
}
//--------------------------------------------------------------------------------------
// Device event callbacks
//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::OnCreateDevice( IDirect3DDevice9* pd3dDevice )
{
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::OnResetDevice( IDirect3DDevice9* pd3dDevice )
{
// Call OnResetDevice on all effect and font objects
for( int i = 0; i < m_EffectCache.GetSize(); ++i )
m_EffectCache[i].pEffect->OnResetDevice();
for( int i = 0; i < m_FontCache.GetSize(); ++i )
m_FontCache[i].pFont->OnResetDevice();
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::OnLostDevice()
{
// Call OnLostDevice on all effect and font objects
for( int i = 0; i < m_EffectCache.GetSize(); ++i )
m_EffectCache[i].pEffect->OnLostDevice();
for( int i = 0; i < m_FontCache.GetSize(); ++i )
m_FontCache[i].pFont->OnLostDevice();
// Release all the default pool textures
for( int i = m_TextureCache.GetSize() - 1; i >= 0; --i )
if( m_TextureCache[i].Pool9 == D3DPOOL_DEFAULT )
{
SAFE_RELEASE( m_TextureCache[i].pTexture9 );
m_TextureCache.Remove( i ); // Remove the entry
}
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTResourceCache::OnDestroyDevice()
{
// Release all resources
for( int i = m_EffectCache.GetSize() - 1; i >= 0; --i )
{
SAFE_RELEASE( m_EffectCache[i].pEffect );
m_EffectCache.Remove( i );
}
for( int i = m_FontCache.GetSize() - 1; i >= 0; --i )
{
SAFE_RELEASE( m_FontCache[i].pFont );
m_FontCache.Remove( i );
}
for( int i = m_TextureCache.GetSize() - 1; i >= 0; --i )
{
SAFE_RELEASE( m_TextureCache[i].pTexture9 );
SAFE_RELEASE( m_TextureCache[i].pSRV11 );
m_TextureCache.Remove( i );
}
return S_OK;
}
//--------------------------------------------------------------------------------------
// Desc: Returns a view matrix for rendering to a face of a cubemap.
//--------------------------------------------------------------------------------------
D3DXMATRIX WINAPI DXUTGetCubeMapViewMatrix( DWORD dwFace )
{
D3DXVECTOR3 vEyePt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vLookDir;
D3DXVECTOR3 vUpDir;
switch( dwFace )
{
case D3DCUBEMAP_FACE_POSITIVE_X:
vLookDir = D3DXVECTOR3( 1.0f, 0.0f, 0.0f );
vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
break;
case D3DCUBEMAP_FACE_NEGATIVE_X:
vLookDir = D3DXVECTOR3( -1.0f, 0.0f, 0.0f );
vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
break;
case D3DCUBEMAP_FACE_POSITIVE_Y:
vLookDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
vUpDir = D3DXVECTOR3( 0.0f, 0.0f, -1.0f );
break;
case D3DCUBEMAP_FACE_NEGATIVE_Y:
vLookDir = D3DXVECTOR3( 0.0f, -1.0f, 0.0f );
vUpDir = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
break;
case D3DCUBEMAP_FACE_POSITIVE_Z:
vLookDir = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
break;
case D3DCUBEMAP_FACE_NEGATIVE_Z:
vLookDir = D3DXVECTOR3( 0.0f, 0.0f, -1.0f );
vUpDir = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
break;
}
// Set the view transform for this cubemap surface
D3DXMATRIXA16 mView;
D3DXMatrixLookAtLH( &mView, &vEyePt, &vLookDir, &vUpDir );
return mView;
}
//--------------------------------------------------------------------------------------
CDXUTLineManager::CDXUTLineManager()
{
m_pd3dDevice = NULL;
m_pD3DXLine = NULL;
}
//--------------------------------------------------------------------------------------
CDXUTLineManager::~CDXUTLineManager()
{
OnDeletedDevice();
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTLineManager::OnCreatedDevice( IDirect3DDevice9* pd3dDevice )
{
m_pd3dDevice = pd3dDevice;
HRESULT hr;
hr = D3DXCreateLine( m_pd3dDevice, &m_pD3DXLine );
if( FAILED( hr ) )
return hr;
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTLineManager::OnResetDevice()
{
if( m_pD3DXLine )
m_pD3DXLine->OnResetDevice();
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTLineManager::OnRender()
{
HRESULT hr;
if( NULL == m_pD3DXLine )
return E_INVALIDARG;
bool bDrawingHasBegun = false;
float fLastWidth = 0.0f;
bool bLastAntiAlias = false;
for( int i = 0; i < m_LinesList.GetSize(); i++ )
{
LINE_NODE* pLineNode = m_LinesList.GetAt( i );
if( pLineNode )
{
if( !bDrawingHasBegun ||
fLastWidth != pLineNode->fWidth ||
bLastAntiAlias != pLineNode->bAntiAlias )
{
if( bDrawingHasBegun )
{
hr = m_pD3DXLine->End();
if( FAILED( hr ) )
return hr;
}
m_pD3DXLine->SetWidth( pLineNode->fWidth );
m_pD3DXLine->SetAntialias( pLineNode->bAntiAlias );
fLastWidth = pLineNode->fWidth;
bLastAntiAlias = pLineNode->bAntiAlias;
hr = m_pD3DXLine->Begin();
if( FAILED( hr ) )
return hr;
bDrawingHasBegun = true;
}
hr = m_pD3DXLine->Draw( pLineNode->pVertexList, pLineNode->dwVertexListCount, pLineNode->Color );
if( FAILED( hr ) )
return hr;
}
}
if( bDrawingHasBegun )
{
hr = m_pD3DXLine->End();
if( FAILED( hr ) )
return hr;
}
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTLineManager::OnLostDevice()
{
if( m_pD3DXLine )
m_pD3DXLine->OnLostDevice();
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTLineManager::OnDeletedDevice()
{
RemoveAllLines();
SAFE_RELEASE( m_pD3DXLine );
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTLineManager::AddLine( int* pnLineID, D3DXVECTOR2* pVertexList, DWORD dwVertexListCount, D3DCOLOR Color,
float fWidth, float fScaleRatio, bool bAntiAlias )
{
if( pVertexList == NULL || dwVertexListCount == 0 )
return E_INVALIDARG;
LINE_NODE* pLineNode = new LINE_NODE;
if( pLineNode == NULL )
return E_OUTOFMEMORY;
ZeroMemory( pLineNode, sizeof( LINE_NODE ) );
pLineNode->nLineID = m_LinesList.GetSize();
pLineNode->Color = Color;
pLineNode->fWidth = fWidth;
pLineNode->bAntiAlias = bAntiAlias;
pLineNode->dwVertexListCount = dwVertexListCount;
if( pnLineID )
*pnLineID = pLineNode->nLineID;
pLineNode->pVertexList = new D3DXVECTOR2[dwVertexListCount];
if( pLineNode->pVertexList == NULL )
{
delete pLineNode;
return E_OUTOFMEMORY;
}
for( DWORD i = 0; i < dwVertexListCount; i++ )
{
pLineNode->pVertexList[i] = pVertexList[i] * fScaleRatio;
}
m_LinesList.Add( pLineNode );
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTLineManager::AddRect( int* pnLineID, RECT rc, D3DCOLOR Color, float fWidth, float fScaleRatio,
bool bAntiAlias )
{
if( fWidth > 2.0f )
{
D3DXVECTOR2 vertexList[8];
vertexList[0].x = ( float )rc.left;
vertexList[0].y = ( float )rc.top - ( fWidth / 2.0f );
vertexList[1].x = ( float )rc.left;
vertexList[1].y = ( float )rc.bottom + ( fWidth / 2.0f );
vertexList[2].x = ( float )rc.left;
vertexList[2].y = ( float )rc.bottom - 0.5f;
vertexList[3].x = ( float )rc.right;
vertexList[3].y = ( float )rc.bottom - 0.5f;
vertexList[4].x = ( float )rc.right;
vertexList[4].y = ( float )rc.bottom + ( fWidth / 2.0f );
vertexList[5].x = ( float )rc.right;
vertexList[5].y = ( float )rc.top - ( fWidth / 2.0f );
vertexList[6].x = ( float )rc.right;
vertexList[6].y = ( float )rc.top;
vertexList[7].x = ( float )rc.left;
vertexList[7].y = ( float )rc.top;
return AddLine( pnLineID, vertexList, 8, Color, fWidth, fScaleRatio, bAntiAlias );
}
else
{
D3DXVECTOR2 vertexList[5];
vertexList[0].x = ( float )rc.left;
vertexList[0].y = ( float )rc.top;
vertexList[1].x = ( float )rc.left;
vertexList[1].y = ( float )rc.bottom;
vertexList[2].x = ( float )rc.right;
vertexList[2].y = ( float )rc.bottom;
vertexList[3].x = ( float )rc.right;
vertexList[3].y = ( float )rc.top;
vertexList[4].x = ( float )rc.left;
vertexList[4].y = ( float )rc.top;
return AddLine( pnLineID, vertexList, 5, Color, fWidth, fScaleRatio, bAntiAlias );
}
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTLineManager::RemoveLine( int nLineID )
{
for( int i = 0; i < m_LinesList.GetSize(); i++ )
{
LINE_NODE* pLineNode = m_LinesList.GetAt( i );
if( pLineNode && pLineNode->nLineID == nLineID )
{
SAFE_DELETE_ARRAY( pLineNode->pVertexList );
delete pLineNode;
m_LinesList.SetAt( i, NULL );
}
}
return S_OK;
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTLineManager::RemoveAllLines()
{
for( int i = 0; i < m_LinesList.GetSize(); i++ )
{
LINE_NODE* pLineNode = m_LinesList.GetAt( i );
if( pLineNode )
{
SAFE_DELETE_ARRAY( pLineNode->pVertexList );
delete pLineNode;
}
}
m_LinesList.RemoveAll();
return S_OK;
}
//--------------------------------------------------------------------------------------
CDXUTTextHelper::CDXUTTextHelper( ID3DXFont* pFont9, ID3DXSprite* pSprite9, int nLineHeight )
{
Init( pFont9, pSprite9, nLineHeight );
}
CDXUTTextHelper::CDXUTTextHelper( ID3D11Device* pd3d11Device, ID3D11DeviceContext* pd3d11DeviceContext, CDXUTDialogResourceManager* pManager, int nLineHeight )
{
Init( NULL, NULL, nLineHeight );
m_pd3d11Device = pd3d11Device;
m_pd3d11DeviceContext = pd3d11DeviceContext;
m_pManager = pManager;
}
CDXUTTextHelper::~CDXUTTextHelper()
{
}
//--------------------------------------------------------------------------------------
void CDXUTTextHelper::Init( ID3DXFont* pFont9, ID3DXSprite* pSprite9,
int nLineHeight )
{
m_pFont9 = pFont9;
m_pSprite9 = pSprite9;
m_clr = D3DXCOLOR( 1, 1, 1, 1 );
m_pt.x = 0;
m_pt.y = 0;
m_nLineHeight = nLineHeight;
m_pd3d11Device = NULL;
m_pd3d11DeviceContext = NULL;
m_pManager = NULL;
// Create a blend state if a sprite is passed in
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTTextHelper::DrawFormattedTextLine( const WCHAR* strMsg, ... )
{
WCHAR strBuffer[512];
va_list args;
va_start( args, strMsg );
vswprintf_s( strBuffer, 512, strMsg, args );
strBuffer[511] = L'\0';
va_end( args );
return DrawTextLine( strBuffer );
}
//--------------------------------------------------------------------------------------
HRESULT CDXUTTextHelper::DrawTextLine( const WCHAR* strMsg )
{
if( NULL == m_pFont9 && NULL == m_pd3d11DeviceContext )
return DXUT_ERR_MSGBOX( L"DrawTextLine", E_INVALIDARG );
HRESULT hr = S_OK;
RECT rc;
SetRect( &rc, m_pt.x, m_pt.y, 0, 0 );
if( m_pFont9 )
hr = m_pFont9->DrawText( m_pSprite9, strMsg, -1, &rc, DT_NOCLIP, m_clr );
else if( m_pd3d11DeviceContext )
DrawText11DXUT( m_pd3d11Device, m_pd3d11DeviceContext, strMsg, rc, m_clr,
(float)m_pManager->m_nBackBufferWidth, (float)m_pManager->m_nBackBufferHeight, false );
if( FAILED( hr ) )
return DXTRACE_ERR_MSGBOX( L"DrawText", hr );
m_pt.y += m_nLineHeight;
return S_OK;
}
HRESULT CDXUTTextHelper::DrawFormattedTextLine( RECT& rc, DWORD dwFlags, const WCHAR* strMsg, ... )
{
WCHAR strBuffer[512];
va_list args;
va_start( args, strMsg );
vswprintf_s( strBuffer, 512, strMsg, args );
strBuffer[511] = L'\0';
va_end( args );
return DrawTextLine( rc, dwFlags, strBuffer );
}
HRESULT CDXUTTextHelper::DrawTextLine( RECT& rc, DWORD dwFlags, const WCHAR* strMsg )
{
if( NULL == m_pFont9 && NULL == m_pd3d11DeviceContext )
return DXUT_ERR_MSGBOX( L"DrawTextLine", E_INVALIDARG );
HRESULT hr = S_OK;
if( m_pFont9 )
hr = m_pFont9->DrawText( m_pSprite9, strMsg, -1, &rc, dwFlags, m_clr );
else if( m_pd3d11DeviceContext )
DrawText11DXUT( m_pd3d11Device, m_pd3d11DeviceContext, strMsg, rc, m_clr,
(float)m_pManager->m_nBackBufferWidth, (float)m_pManager->m_nBackBufferHeight, false );
if( FAILED( hr ) )
return DXTRACE_ERR_MSGBOX( L"DrawText", hr );
m_pt.y += m_nLineHeight;
return S_OK;
}
//--------------------------------------------------------------------------------------
void CDXUTTextHelper::Begin()
{
if( m_pSprite9 )
m_pSprite9->Begin( D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE );
if( m_pd3d11DeviceContext )
{
m_pManager->StoreD3D11State( m_pd3d11DeviceContext );
m_pManager->ApplyRenderUI11( m_pd3d11DeviceContext );
}
}
void CDXUTTextHelper::End()
{
if( m_pSprite9 )
m_pSprite9->End();
if( m_pd3d11DeviceContext )
{
m_pManager->RestoreD3D11State( m_pd3d11DeviceContext );
}
}