DXUTmisc.cpp
资源名称:Direct3D.rar [点击查看]
上传用户:junlon
上传日期:2022-01-05
资源大小:39075k
文件大小:130k
源码类别:
DirextX编程
开发平台:
Visual C++
- //--------------------------------------------------------------------------------------
- // File: DXUTMisc.cpp
- //
- // Shortcut macros and functions for using DX objects
- //
- // Copyright (c) Microsoft Corporation. All rights reserved
- //--------------------------------------------------------------------------------------
- #include "dxstdafx.h"
- #define DXUT_GAMEPAD_TRIGGER_THRESHOLD 30
- #undef min // use __min instead
- #undef max // use __max instead
- //--------------------------------------------------------------------------------------
- // Global/Static Members
- //--------------------------------------------------------------------------------------
- CDXUTResourceCache& DXUTGetGlobalResourceCache()
- {
- // Using an accessor function gives control of the construction order
- static CDXUTResourceCache cache;
- return cache;
- }
- CDXUTTimer* DXUTGetGlobalTimer()
- {
- // Using an accessor function gives control of the construction order
- static CDXUTTimer timer;
- return &timer;
- }
- //--------------------------------------------------------------------------------------
- // Internal functions forward declarations
- //--------------------------------------------------------------------------------------
- bool DXUTFindMediaSearchTypicalDirs( WCHAR* strSearchPath, int cchSearch, LPCWSTR strLeaf, WCHAR* strExePath, WCHAR* strExeName );
- bool DXUTFindMediaSearchParentDirs( WCHAR* strSearchPath, int cchSearch, WCHAR* strStartAt, 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 DXUTDisplaySwitchingToREFWarning()
- {
- if( DXUTGetShowMsgBoxOnError() )
- {
- // Open the appropriate registry key
- DWORD dwSkipWarning = 0;
- HKEY hKey;
- LONG lResult = RegOpenKeyEx( HKEY_CURRENT_USER, L"Software\Microsoft\DirectX 9.0 SDK", 0, KEY_READ, &hKey );
- if( ERROR_SUCCESS == lResult )
- {
- DWORD dwType;
- DWORD dwSize = sizeof(DWORD);
- lResult = RegQueryValueEx( hKey, L"Skip Warning On REF", NULL, &dwType, (BYTE*)&dwSkipWarning, &dwSize );
- RegCloseKey( hKey );
- }
- 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[14]; 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 Sans Serif",
- {{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|BS_DEFPUSHBUTTON,0,80,39,50,14,IDYES},0xFFFF,0x0080,0,0,0}, // Yes button
- {{WS_CHILD|WS_VISIBLE,0,133,39,50,14,IDNO},0xFFFF,0x0080,0,0,0}, // No button
- {{WS_CHILD|WS_VISIBLE|BS_CHECKBOX,0,7,59,70,16,IDIGNORE},0xFFFF,0x0080,0,0,0}, // checkbox
- };
- int nResult = (int) DialogBoxIndirect( DXUTGetHINSTANCE(), (DLGTEMPLATE*)&dtp, DXUTGetHWND(), DisplaySwitchToREFWarningProc );
- if( (nResult & 0x80) == 0x80 ) // "Don't show again" checkbox was checked
- {
- lResult = RegOpenKeyEx( HKEY_CURRENT_USER, L"Software\Microsoft\DirectX 9.0 SDK", 0, KEY_WRITE, &hKey );
- if( ERROR_SUCCESS == lResult )
- {
- dwSkipWarning = 1;
- RegSetValueEx( hKey, L"Skip Warning On REF", 0, REG_DWORD, (BYTE*)&dwSkipWarning, sizeof(DWORD) );
- RegCloseKey( hKey );
- }
- }
- // 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));
- SetDlgItemText( hDlg, 0x101, L"Switching to the Direct3D reference rasterizer, a software devicenthat implements the entire Direct3D feature set, but runs very slowly.nDo you wish to continue?" );
- 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;
- }
- //--------------------------------------------------------------------------------------
- CDXUTTimer::CDXUTTimer()
- {
- m_bTimerStopped = true;
- m_llQPFTicksPerSec = 0;
- m_llStopTime = 0;
- m_llLastElapsedTime = 0;
- m_llBaseTime = 0;
- // Use QueryPerformanceFrequency to get the frequency of the counter
- LARGE_INTEGER qwTicksPerSec;
- QueryPerformanceFrequency( &qwTicksPerSec );
- m_llQPFTicksPerSec = qwTicksPerSec.QuadPart;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTTimer::Reset()
- {
- LARGE_INTEGER qwTime = GetAdjustedCurrentTime();
- m_llBaseTime = qwTime.QuadPart;
- m_llLastElapsedTime = qwTime.QuadPart;
- m_llStopTime = 0;
- m_bTimerStopped = FALSE;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTTimer::Start()
- {
- // Get the current time
- LARGE_INTEGER qwTime;
- QueryPerformanceCounter( &qwTime );
- if( m_bTimerStopped )
- m_llBaseTime += qwTime.QuadPart - m_llStopTime;
- m_llStopTime = 0;
- m_llLastElapsedTime = qwTime.QuadPart;
- m_bTimerStopped = FALSE;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTTimer::Stop()
- {
- if( !m_bTimerStopped )
- {
- LARGE_INTEGER qwTime;
- QueryPerformanceCounter( &qwTime );
- m_llStopTime = qwTime.QuadPart;
- m_llLastElapsedTime = qwTime.QuadPart;
- m_bTimerStopped = TRUE;
- }
- }
- //--------------------------------------------------------------------------------------
- void CDXUTTimer::Advance()
- {
- m_llStopTime += m_llQPFTicksPerSec/10;
- }
- //--------------------------------------------------------------------------------------
- double CDXUTTimer::GetAbsoluteTime()
- {
- LARGE_INTEGER qwTime;
- QueryPerformanceCounter( &qwTime );
- double fTime = qwTime.QuadPart / (double) m_llQPFTicksPerSec;
- return fTime;
- }
- //--------------------------------------------------------------------------------------
- double CDXUTTimer::GetTime()
- {
- LARGE_INTEGER qwTime = GetAdjustedCurrentTime();
- double fAppTime = (double) ( qwTime.QuadPart - m_llBaseTime ) / (double) m_llQPFTicksPerSec;
- return fAppTime;
- }
- //--------------------------------------------------------------------------------------
- void CDXUTTimer::GetTimeValues( double* pfTime, double* pfAbsoluteTime, float* pfElapsedTime )
- {
- assert( pfTime && pfAbsoluteTime && pfElapsedTime );
- LARGE_INTEGER qwTime = GetAdjustedCurrentTime();
- float fElapsedTime = (float) ((double) ( qwTime.QuadPart - m_llLastElapsedTime ) / (double) m_llQPFTicksPerSec);
- m_llLastElapsedTime = qwTime.QuadPart;
- // Clamp the timer to non-negative values to ensure the timer is accurate.
- // fElapsedTime can be outside this range if processor goes into a
- // power save mode or we somehow get shuffled to another processor.
- // However, the main thread should call SetThreadAffinityMask to ensure that
- // we don't get shuffled to another processor. Other worker threads should NOT call
- // SetThreadAffinityMask, but use a shared copy of the timer data gathered from
- // the main thread.
- if( fElapsedTime < 0.0f )
- fElapsedTime = 0.0f;
- *pfAbsoluteTime = qwTime.QuadPart / (double) m_llQPFTicksPerSec;
- *pfTime = ( qwTime.QuadPart - m_llBaseTime ) / (double) m_llQPFTicksPerSec;
- *pfElapsedTime = fElapsedTime;
- }
- //--------------------------------------------------------------------------------------
- double CDXUTTimer::GetElapsedTime()
- {
- LARGE_INTEGER qwTime = GetAdjustedCurrentTime();
- double fElapsedTime = (double) ( qwTime.QuadPart - m_llLastElapsedTime ) / (double) m_llQPFTicksPerSec;
- m_llLastElapsedTime = qwTime.QuadPart;
- // See the explanation about clamping in CDXUTTimer::GetTimeValues()
- if( fElapsedTime < 0.0f )
- fElapsedTime = 0.0f;
- return fElapsedTime;
- }
- //--------------------------------------------------------------------------------------
- // If stopped, returns time when stopped otherwise returns current time
- //--------------------------------------------------------------------------------------
- LARGE_INTEGER CDXUTTimer::GetAdjustedCurrentTime()
- {
- LARGE_INTEGER qwTime;
- if( m_llStopTime != 0 )
- qwTime.QuadPart = m_llStopTime;
- else
- QueryPerformanceCounter( &qwTime );
- return qwTime;
- }
- //--------------------------------------------------------------------------------------
- bool CDXUTTimer::IsStopped()
- {
- return m_bTimerStopped;
- }
- //--------------------------------------------------------------------------------------
- // Limit the current thread to one processor (the current one). This ensures that timing code
- // runs on only one processor, and will not suffer any ill effects from power management.
- // See "Game Timing and Multicore Processors" for more details
- //--------------------------------------------------------------------------------------
- void CDXUTTimer::LimitThreadAffinityToCurrentProc()
- {
- HANDLE hCurrentProcess = GetCurrentProcess();
- // Get the processor affinity mask for this process
- DWORD_PTR dwProcessAffinityMask = 0;
- DWORD_PTR dwSystemAffinityMask = 0;
- if( GetProcessAffinityMask( hCurrentProcess, &dwProcessAffinityMask, &dwSystemAffinityMask ) != 0 && dwProcessAffinityMask )
- {
- // Find the lowest processor that our process is allows to run against
- DWORD_PTR dwAffinityMask = ( dwProcessAffinityMask & ((~dwProcessAffinityMask) + 1 ) );
- // Set this as the processor that our thread must always run against
- // This must be a subset of the process affinity mask
- HANDLE hCurrentThread = GetCurrentThread();
- if( INVALID_HANDLE_VALUE != hCurrentThread )
- {
- SetThreadAffinityMask( hCurrentThread, dwAffinityMask );
- CloseHandle( hCurrentThread );
- }
- }
- CloseHandle( hCurrentProcess );
- }
- //--------------------------------------------------------------------------------------
- // Returns pointer to static media search buffer
- //--------------------------------------------------------------------------------------
- WCHAR* DXUTMediaSearchPath()
- {
- static WCHAR s_strMediaSearchPath[MAX_PATH] = {0};
- return s_strMediaSearchPath;
- }
- //--------------------------------------------------------------------------------------
- LPCWSTR DXUTGetMediaSearchPath()
- {
- return DXUTMediaSearchPath();
- }
- //--------------------------------------------------------------------------------------
- HRESULT DXUTSetMediaSearchPath( LPCWSTR strPath )
- {
- HRESULT hr;
- WCHAR* s_strSearchPath = DXUTMediaSearchPath();
- hr = StringCchCopy( s_strSearchPath, MAX_PATH, strPath );
- if( SUCCEEDED(hr) )
- {
- // append slash if needed
- size_t ch;
- hr = StringCchLength( s_strSearchPath, MAX_PATH, &ch );
- if( SUCCEEDED(hr) && s_strSearchPath[ch-1] != L'\')
- {
- hr = StringCchCat( 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 DXUTFindDXSDKMediaFileCch( WCHAR* strDestPath, int cchDest, 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 )
- {
- StringCchCopy( 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"
- StringCchPrintf( 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
- StringCchCopy( 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 "mediastrFilename" as the leaf name
- StringCchPrintf( 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 "mediastrFilename" 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
- StringCchCopy( strDestPath, cchDest, strFilename );
- return DXUTERR_MEDIANOTFOUND;
- }
- //--------------------------------------------------------------------------------------
- // Search a set of typical directories
- //--------------------------------------------------------------------------------------
- bool DXUTFindMediaSearchTypicalDirs( WCHAR* strSearchPath, int cchSearch, LPCWSTR strLeaf,
- WCHAR* strExePath, WCHAR* strExeName )
- {
- // Typical directories:
- // .
- // ..
- // ....
- // %EXE_DIR%
- // %EXE_DIR%..
- // %EXE_DIR%....
- // %EXE_DIR%..%EXE_NAME%
- // %EXE_DIR%....%EXE_NAME%
- // DXSDK media path
- // Search in .
- StringCchCopy( strSearchPath, cchSearch, strLeaf );
- if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
- return true;
- // Search in ..
- StringCchPrintf( strSearchPath, cchSearch, L"..\%s", strLeaf );
- if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
- return true;
- // Search in ....
- StringCchPrintf( strSearchPath, cchSearch, L"..\..\%s", strLeaf );
- if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
- return true;
- // Search in ....
- StringCchPrintf( strSearchPath, cchSearch, L"..\..\%s", strLeaf );
- if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
- return true;
- // Search in the %EXE_DIR%
- StringCchPrintf( strSearchPath, cchSearch, L"%s\%s", strExePath, strLeaf );
- if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
- return true;
- // Search in the %EXE_DIR%..
- StringCchPrintf( strSearchPath, cchSearch, L"%s\..\%s", strExePath, strLeaf );
- if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
- return true;
- // Search in the %EXE_DIR%....
- StringCchPrintf( 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
- StringCchPrintf( 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
- StringCchPrintf( strSearchPath, cchSearch, L"%s\..\..\%s\%s", strExePath, strExeName, strLeaf );
- if( GetFileAttributes( strSearchPath ) != 0xFFFFFFFF )
- return true;
- // Search in media search dir
- WCHAR* s_strSearchPath = DXUTMediaSearchPath();
- if( s_strSearchPath[0] != 0 )
- {
- StringCchPrintf( 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( WCHAR* strSearchPath, int cchSearch, WCHAR* strStartAt, 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 != ' ' )
- {
- StringCchPrintf( strFullFileName, MAX_PATH, L"%s\%s", strFullPath, strLeafName );
- if( GetFileAttributes( strFullFileName ) != 0xFFFFFFFF )
- {
- StringCchCopy( strSearchPath, cchSearch, strFullFileName );
- return true;
- }
- StringCchPrintf( 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::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.Usage == Usage &&
- Entry.Format == Format &&
- Entry.Pool == Pool &&
- Entry.Type == D3DRTYPE_TEXTURE )
- {
- // A match is found. Obtain the IDirect3DTexture9 interface and return that.
- return Entry.pTexture->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;
- StringCchCopy( NewEntry.wszSource, MAX_PATH, pSrcFile );
- NewEntry.Width = Width;
- NewEntry.Height = Height;
- NewEntry.MipLevels = MipLevels;
- NewEntry.Usage = Usage;
- NewEntry.Format = Format;
- NewEntry.Pool = Pool;
- NewEntry.Type = D3DRTYPE_TEXTURE;
- (*ppTexture)->QueryInterface( IID_IDirect3DBaseTexture9, (LPVOID*)&NewEntry.pTexture );
- 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.Usage == Usage &&
- Entry.Format == Format &&
- Entry.Pool == Pool &&
- Entry.Type == D3DRTYPE_TEXTURE )
- {
- // A match is found. Obtain the IDirect3DTexture9 interface and return that.
- return Entry.pTexture->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;
- StringCchCopy( NewEntry.wszSource, MAX_PATH, pSrcResource );
- NewEntry.Width = Width;
- NewEntry.Height = Height;
- NewEntry.MipLevels = MipLevels;
- NewEntry.Usage = Usage;
- NewEntry.Format = Format;
- NewEntry.Pool = Pool;
- NewEntry.Type = D3DRTYPE_TEXTURE;
- (*ppTexture)->QueryInterface( IID_IDirect3DBaseTexture9, (LPVOID*)&NewEntry.pTexture );
- 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.Usage == Usage &&
- Entry.Format == Format &&
- Entry.Pool == Pool &&
- Entry.Type == D3DRTYPE_CUBETEXTURE )
- {
- // A match is found. Obtain the IDirect3DCubeTexture9 interface and return that.
- return Entry.pTexture->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;
- StringCchCopy( NewEntry.wszSource, MAX_PATH, pSrcFile );
- NewEntry.Width = Size;
- NewEntry.MipLevels = MipLevels;
- NewEntry.Usage = Usage;
- NewEntry.Format = Format;
- NewEntry.Pool = Pool;
- NewEntry.Type = D3DRTYPE_CUBETEXTURE;
- (*ppCubeTexture)->QueryInterface( IID_IDirect3DBaseTexture9, (LPVOID*)&NewEntry.pTexture );
- 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.Usage == Usage &&
- Entry.Format == Format &&
- Entry.Pool == Pool &&
- Entry.Type == D3DRTYPE_CUBETEXTURE )
- {
- // A match is found. Obtain the IDirect3DCubeTexture9 interface and return that.
- return Entry.pTexture->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;
- StringCchCopy( NewEntry.wszSource, MAX_PATH, pSrcResource );
- NewEntry.Width = Size;
- NewEntry.MipLevels = MipLevels;
- NewEntry.Usage = Usage;
- NewEntry.Format = Format;
- NewEntry.Pool = Pool;
- NewEntry.Type = D3DRTYPE_CUBETEXTURE;
- (*ppCubeTexture)->QueryInterface( IID_IDirect3DBaseTexture9, (LPVOID*)&NewEntry.pTexture );
- 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.Usage == Usage &&
- Entry.Format == Format &&
- Entry.Pool == Pool &&
- Entry.Type == D3DRTYPE_VOLUMETEXTURE )
- {
- // A match is found. Obtain the IDirect3DVolumeTexture9 interface and return that.
- return Entry.pTexture->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;
- StringCchCopy( NewEntry.wszSource, MAX_PATH, pSrcFile );
- NewEntry.Width = Width;
- NewEntry.Height = Height;
- NewEntry.Depth = Depth;
- NewEntry.MipLevels = MipLevels;
- NewEntry.Usage = Usage;
- NewEntry.Format = Format;
- NewEntry.Pool = Pool;
- NewEntry.Type = D3DRTYPE_VOLUMETEXTURE;
- (*ppTexture)->QueryInterface( IID_IDirect3DBaseTexture9, (LPVOID*)&NewEntry.pTexture );
- 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.Usage == Usage &&
- Entry.Format == Format &&
- Entry.Pool == Pool &&
- Entry.Type == D3DRTYPE_VOLUMETEXTURE )
- {
- // A match is found. Obtain the IDirect3DVolumeTexture9 interface and return that.
- return Entry.pTexture->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;
- StringCchCopy( NewEntry.wszSource, MAX_PATH, pSrcResource );
- NewEntry.Width = Width;
- NewEntry.Height = Height;
- NewEntry.Depth = Depth;
- NewEntry.MipLevels = MipLevels;
- NewEntry.Usage = Usage;
- NewEntry.Format = Format;
- NewEntry.Pool = Pool;
- NewEntry.Type = D3DRTYPE_VOLUMETEXTURE;
- (*ppVolumeTexture)->QueryInterface( IID_IDirect3DBaseTexture9, (LPVOID*)&NewEntry.pTexture );
- 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;
- StringCchCopy( 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;
- StringCchCopy( 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;
- StringCchCopy( 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].Pool == D3DPOOL_DEFAULT )
- {
- SAFE_RELEASE( m_TextureCache[i].pTexture );
- 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].pTexture );
- m_TextureCache.Remove( i );
- }
- return S_OK;
- }
- //--------------------------------------------------------------------------------------
- CD3DArcBall::CD3DArcBall()
- {
- Reset();
- m_vDownPt = D3DXVECTOR3(0,0,0);
- m_vCurrentPt = D3DXVECTOR3(0,0,0);
- m_Offset.x = m_Offset.y = 0;
- RECT rc;
- GetClientRect( GetForegroundWindow(), &rc );
- SetWindow( rc.right, rc.bottom );
- }
- //--------------------------------------------------------------------------------------
- void CD3DArcBall::Reset()
- {
- D3DXQuaternionIdentity( &m_qDown );
- D3DXQuaternionIdentity( &m_qNow );
- D3DXMatrixIdentity( &m_mRotation );
- D3DXMatrixIdentity( &m_mTranslation );
- D3DXMatrixIdentity( &m_mTranslationDelta );
- m_bDrag = FALSE;
- m_fRadiusTranslation = 1.0f;
- m_fRadius = 1.0f;
- }
- //--------------------------------------------------------------------------------------
- D3DXVECTOR3 CD3DArcBall::ScreenToVector( float fScreenPtX, float fScreenPtY )
- {
- // Scale to screen
- FLOAT x = -(fScreenPtX - m_Offset.x - m_nWidth/2) / (m_fRadius*m_nWidth/2);
- FLOAT y = (fScreenPtY - m_Offset.y - m_nHeight/2) / (m_fRadius*m_nHeight/2);
- FLOAT z = 0.0f;
- FLOAT mag = x*x + y*y;
- if( mag > 1.0f )
- {
- FLOAT scale = 1.0f/sqrtf(mag);
- x *= scale;
- y *= scale;
- }
- else
- z = sqrtf( 1.0f - mag );
- // Return vector
- return D3DXVECTOR3( x, y, z );
- }
- //--------------------------------------------------------------------------------------
- D3DXQUATERNION CD3DArcBall::QuatFromBallPoints(const D3DXVECTOR3 &vFrom, const D3DXVECTOR3 &vTo)
- {
- D3DXVECTOR3 vPart;
- float fDot = D3DXVec3Dot(&vFrom, &vTo);
- D3DXVec3Cross(&vPart, &vFrom, &vTo);
- return D3DXQUATERNION(vPart.x, vPart.y, vPart.z, fDot);
- }
- //--------------------------------------------------------------------------------------
- void CD3DArcBall::OnBegin( int nX, int nY )
- {
- // Only enter the drag state if the click falls
- // inside the click rectangle.
- if( nX >= m_Offset.x &&
- nX < m_Offset.x + m_nWidth &&
- nY >= m_Offset.y &&
- nY < m_Offset.y + m_nHeight )
- {
- m_bDrag = true;
- m_qDown = m_qNow;
- m_vDownPt = ScreenToVector( (float)nX, (float)nY );
- }
- }
- //--------------------------------------------------------------------------------------
- void CD3DArcBall::OnMove( int nX, int nY )
- {
- if (m_bDrag)
- {
- m_vCurrentPt = ScreenToVector( (float)nX, (float)nY );
- m_qNow = m_qDown * QuatFromBallPoints( m_vDownPt, m_vCurrentPt );
- }
- }
- //--------------------------------------------------------------------------------------
- void CD3DArcBall::OnEnd()
- {
- m_bDrag = false;
- }
- //--------------------------------------------------------------------------------------
- // Desc:
- //--------------------------------------------------------------------------------------
- LRESULT CD3DArcBall::HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- // Current mouse position
- int iMouseX = (short)LOWORD(lParam);
- int iMouseY = (short)HIWORD(lParam);
- switch( uMsg )
- {
- case WM_LBUTTONDOWN:
- case WM_LBUTTONDBLCLK:
- SetCapture( hWnd );
- OnBegin( iMouseX, iMouseY );
- return TRUE;
- case WM_LBUTTONUP:
- ReleaseCapture();
- OnEnd();
- return TRUE;
- case WM_CAPTURECHANGED:
- if( (HWND)lParam != hWnd )
- {
- ReleaseCapture();
- OnEnd();
- }
- return TRUE;
- case WM_RBUTTONDOWN:
- case WM_RBUTTONDBLCLK:
- case WM_MBUTTONDOWN:
- case WM_MBUTTONDBLCLK:
- SetCapture( hWnd );
- // Store off the position of the cursor when the button is pressed
- m_ptLastMouse.x = iMouseX;
- m_ptLastMouse.y = iMouseY;
- return TRUE;
- case WM_RBUTTONUP:
- case WM_MBUTTONUP:
- ReleaseCapture();
- return TRUE;
- case WM_MOUSEMOVE:
- if( MK_LBUTTON&wParam )
- {
- OnMove( iMouseX, iMouseY );
- }
- else if( (MK_RBUTTON&wParam) || (MK_MBUTTON&wParam) )
- {
- // Normalize based on size of window and bounding sphere radius
- FLOAT fDeltaX = ( m_ptLastMouse.x-iMouseX ) * m_fRadiusTranslation / m_nWidth;
- FLOAT fDeltaY = ( m_ptLastMouse.y-iMouseY ) * m_fRadiusTranslation / m_nHeight;
- if( wParam & MK_RBUTTON )
- {
- D3DXMatrixTranslation( &m_mTranslationDelta, -2*fDeltaX, 2*fDeltaY, 0.0f );
- D3DXMatrixMultiply( &m_mTranslation, &m_mTranslation, &m_mTranslationDelta );
- }
- else // wParam & MK_MBUTTON
- {
- D3DXMatrixTranslation( &m_mTranslationDelta, 0.0f, 0.0f, 5*fDeltaY );
- D3DXMatrixMultiply( &m_mTranslation, &m_mTranslation, &m_mTranslationDelta );
- }
- // Store mouse coordinate
- m_ptLastMouse.x = iMouseX;
- m_ptLastMouse.y = iMouseY;
- }
- return TRUE;
- }
- return FALSE;
- }
- //--------------------------------------------------------------------------------------
- // Constructor
- //--------------------------------------------------------------------------------------
- CBaseCamera::CBaseCamera()
- {
- m_cKeysDown = 0;
- ZeroMemory( m_aKeys, sizeof(BYTE)*CAM_MAX_KEYS );
- ZeroMemory( m_GamePad, sizeof(DXUT_GAMEPAD)*DXUT_MAX_CONTROLLERS );
- // Set attributes for the view matrix
- D3DXVECTOR3 vEyePt = D3DXVECTOR3(0.0f,0.0f,0.0f);
- D3DXVECTOR3 vLookatPt = D3DXVECTOR3(0.0f,0.0f,1.0f);
- // Setup the view matrix
- SetViewParams( &vEyePt, &vLookatPt );
- // Setup the projection matrix
- SetProjParams( D3DX_PI/4, 1.0f, 1.0f, 1000.0f );
- GetCursorPos( &m_ptLastMousePosition );
- m_bMouseLButtonDown = false;
- m_bMouseMButtonDown = false;
- m_bMouseRButtonDown = false;
- m_nCurrentButtonMask = 0;
- m_nMouseWheelDelta = 0;
- m_fCameraYawAngle = 0.0f;
- m_fCameraPitchAngle = 0.0f;
- SetRect( &m_rcDrag, LONG_MIN, LONG_MIN, LONG_MAX, LONG_MAX );
- m_vVelocity = D3DXVECTOR3(0,0,0);
- m_bMovementDrag = false;
- m_vVelocityDrag = D3DXVECTOR3(0,0,0);
- m_fDragTimer = 0.0f;
- m_fTotalDragTimeToZero = 0.25;
- m_vRotVelocity = D3DXVECTOR2(0,0);
- m_fRotationScaler = 0.01f;
- m_fMoveScaler = 5.0f;
- m_bInvertPitch = false;
- m_bEnableYAxisMovement = true;
- m_bEnablePositionMovement = true;
- m_vMouseDelta = D3DXVECTOR2(0,0);
- m_fFramesToSmoothMouseData = 2.0f;
- m_bClipToBoundary = false;
- m_vMinBoundary = D3DXVECTOR3(-1,-1,-1);
- m_vMaxBoundary = D3DXVECTOR3(1,1,1);
- }
- //--------------------------------------------------------------------------------------
- // Client can call this to change the position and direction of camera
- //--------------------------------------------------------------------------------------
- VOID CBaseCamera::SetViewParams( D3DXVECTOR3* pvEyePt, D3DXVECTOR3* pvLookatPt )
- {
- if( NULL == pvEyePt || NULL == pvLookatPt )
- return;
- m_vDefaultEye = m_vEye = *pvEyePt;
- m_vDefaultLookAt = m_vLookAt = *pvLookatPt;
- // Calc the view matrix
- D3DXVECTOR3 vUp(0,1,0);
- D3DXMatrixLookAtLH( &m_mView, pvEyePt, pvLookatPt, &vUp );
- D3DXMATRIX mInvView;
- D3DXMatrixInverse( &mInvView, NULL, &m_mView );
- // The axis basis vectors and camera position are stored inside the
- // position matrix in the 4 rows of the camera's world matrix.
- // To figure out the yaw/pitch of the camera, we just need the Z basis vector
- D3DXVECTOR3* pZBasis = (D3DXVECTOR3*) &mInvView._31;
- m_fCameraYawAngle = atan2f( pZBasis->x, pZBasis->z );
- float fLen = sqrtf(pZBasis->z*pZBasis->z + pZBasis->x*pZBasis->x);
- m_fCameraPitchAngle = -atan2f( pZBasis->y, fLen );
- }
- VOID CBaseCamera::SetViewParams( D3DXVECTOR3* pvEyePt, D3DXVECTOR3* pvLookatPt, D3DXVECTOR3* pvUpVec )
- {
- if( NULL == pvEyePt || NULL == pvLookatPt )
- return;
- if( D3DXVec3Length( pvUpVec ) == 0.0f )
- return;
- m_vDefaultEye = m_vEye = *pvEyePt;
- m_vDefaultLookAt = m_vLookAt = *pvLookatPt;
- // Calc the view matrix
- D3DXMatrixLookAtLH( &m_mView, pvEyePt, pvLookatPt, pvUpVec );
- D3DXMATRIX mInvView;
- D3DXMatrixInverse( &mInvView, NULL, &m_mView );
- // The axis basis vectors and camera position are stored inside the
- // position matrix in the 4 rows of the camera's world matrix.
- // To figure out the yaw/pitch of the camera, we just need the Z basis vector
- D3DXVECTOR3* pZBasis = (D3DXVECTOR3*) &mInvView._31;
- m_fCameraYawAngle = atan2f( pZBasis->x, pZBasis->z );
- float fLen = sqrtf(pZBasis->z*pZBasis->z + pZBasis->x*pZBasis->x);
- m_fCameraPitchAngle = -atan2f( pZBasis->y, fLen );
- }
- //--------------------------------------------------------------------------------------
- // Calculates the projection matrix based on input params
- //--------------------------------------------------------------------------------------
- VOID CBaseCamera::SetProjParams( FLOAT fFOV, FLOAT fAspect, FLOAT fNearPlane,
- FLOAT fFarPlane )
- {
- // Set attributes for the projection matrix
- m_fFOV = fFOV;
- m_fAspect = fAspect;
- m_fNearPlane = fNearPlane;
- m_fFarPlane = fFarPlane;
- D3DXMatrixPerspectiveFovLH( &m_mProj, fFOV, fAspect, fNearPlane, fFarPlane );
- }
- //--------------------------------------------------------------------------------------
- // Call this from your message proc so this class can handle window messages
- //--------------------------------------------------------------------------------------
- LRESULT CBaseCamera::HandleMessages( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- UNREFERENCED_PARAMETER( hWnd );
- UNREFERENCED_PARAMETER( lParam );
- switch( uMsg )
- {
- case WM_KEYDOWN:
- {
- // Map this key to a D3DUtil_CameraKeys enum and update the
- // state of m_aKeys[] by adding the KEY_WAS_DOWN_MASK|KEY_IS_DOWN_MASK mask
- // only if the key is not down
- D3DUtil_CameraKeys mappedKey = MapKey( (UINT)wParam );
- if( mappedKey != CAM_UNKNOWN )
- {
- if( FALSE == IsKeyDown(m_aKeys[mappedKey]) )
- {
- m_aKeys[ mappedKey ] = KEY_WAS_DOWN_MASK | KEY_IS_DOWN_MASK;
- ++m_cKeysDown;
- }
- }
- break;
- }
- case WM_KEYUP:
- {
- // Map this key to a D3DUtil_CameraKeys enum and update the
- // state of m_aKeys[] by removing the KEY_IS_DOWN_MASK mask.
- D3DUtil_CameraKeys mappedKey = MapKey( (UINT)wParam );
- if( mappedKey != CAM_UNKNOWN && (DWORD)mappedKey < 8 )
- {
- m_aKeys[ mappedKey ] &= ~KEY_IS_DOWN_MASK;
- --m_cKeysDown;
- }
- break;
- }
- case WM_RBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_LBUTTONDOWN:
- case WM_RBUTTONDBLCLK:
- case WM_MBUTTONDBLCLK:
- case WM_LBUTTONDBLCLK:
- {
- // Compute the drag rectangle in screen coord.
- POINT ptCursor = { (short)LOWORD(lParam), (short)HIWORD(lParam) };
- // Update member var state
- if( ( uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONDBLCLK ) && PtInRect( &m_rcDrag, ptCursor ) )
- { m_bMouseLButtonDown = true; m_nCurrentButtonMask |= MOUSE_LEFT_BUTTON; }
- if( ( uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONDBLCLK ) && PtInRect( &m_rcDrag, ptCursor ) )
- { m_bMouseMButtonDown = true; m_nCurrentButtonMask |= MOUSE_MIDDLE_BUTTON; }
- if( ( uMsg == WM_RBUTTONDOWN || uMsg == WM_RBUTTONDBLCLK ) && PtInRect( &m_rcDrag, ptCursor ) )
- { m_bMouseRButtonDown = true; m_nCurrentButtonMask |= MOUSE_RIGHT_BUTTON; }
- // Capture the mouse, so if the mouse button is
- // released outside the window, we'll get the WM_LBUTTONUP message
- SetCapture(hWnd);
- GetCursorPos( &m_ptLastMousePosition );
- return TRUE;
- }
- case WM_RBUTTONUP:
- case WM_MBUTTONUP:
- case WM_LBUTTONUP:
- {
- // Update member var state
- if( uMsg == WM_LBUTTONUP ) { m_bMouseLButtonDown = false; m_nCurrentButtonMask &= ~MOUSE_LEFT_BUTTON; }
- if( uMsg == WM_MBUTTONUP ) { m_bMouseMButtonDown = false; m_nCurrentButtonMask &= ~MOUSE_MIDDLE_BUTTON; }
- if( uMsg == WM_RBUTTONUP ) { m_bMouseRButtonDown = false; m_nCurrentButtonMask &= ~MOUSE_RIGHT_BUTTON; }
- // Release the capture if no mouse buttons down
- if( !m_bMouseLButtonDown &&
- !m_bMouseRButtonDown &&
- !m_bMouseMButtonDown )
- {
- ReleaseCapture();
- }
- break;
- }
- case WM_CAPTURECHANGED:
- {
- if( (HWND)lParam != hWnd )
- {
- if( (m_nCurrentButtonMask & MOUSE_LEFT_BUTTON) ||
- (m_nCurrentButtonMask & MOUSE_MIDDLE_BUTTON) ||
- (m_nCurrentButtonMask & MOUSE_RIGHT_BUTTON) )
- {
- m_bMouseLButtonDown = false;
- m_bMouseMButtonDown = false;
- m_bMouseRButtonDown = false;
- m_nCurrentButtonMask &= ~MOUSE_LEFT_BUTTON;
- m_nCurrentButtonMask &= ~MOUSE_MIDDLE_BUTTON;
- m_nCurrentButtonMask &= ~MOUSE_RIGHT_BUTTON;
- ReleaseCapture();
- }
- }
- break;
- }
- case WM_MOUSEWHEEL:
- // Update member var state
- m_nMouseWheelDelta = (short)HIWORD(wParam) / 120;
- break;
- }
- return FALSE;
- }
- //--------------------------------------------------------------------------------------
- // Figure out the velocity based on keyboard input & drag if any
- //--------------------------------------------------------------------------------------
- void CBaseCamera::GetInput( bool bGetKeyboardInput, bool bGetMouseInput, bool bGetGamepadInput, bool bResetCursorAfterMove )
- {
- m_vKeyboardDirection = D3DXVECTOR3(0,0,0);
- if( bGetKeyboardInput )
- {
- // Update acceleration vector based on keyboard state
- if( IsKeyDown(m_aKeys[CAM_MOVE_FORWARD]) )
- m_vKeyboardDirection.z += 1.0f;
- if( IsKeyDown(m_aKeys[CAM_MOVE_BACKWARD]) )
- m_vKeyboardDirection.z -= 1.0f;
- if( m_bEnableYAxisMovement )
- {
- if( IsKeyDown(m_aKeys[CAM_MOVE_UP]) )
- m_vKeyboardDirection.y += 1.0f;
- if( IsKeyDown(m_aKeys[CAM_MOVE_DOWN]) )
- m_vKeyboardDirection.y -= 1.0f;
- }
- if( IsKeyDown(m_aKeys[CAM_STRAFE_RIGHT]) )
- m_vKeyboardDirection.x += 1.0f;
- if( IsKeyDown(m_aKeys[CAM_STRAFE_LEFT]) )
- m_vKeyboardDirection.x -= 1.0f;
- }
- if( bGetMouseInput )
- {
- // Get current position of mouse
- POINT ptCurMouseDelta;
- POINT ptCurMousePos;
- if( GetCursorPos( &ptCurMousePos ) )
- {
- // Calc how far it's moved since last frame
- ptCurMouseDelta.x = ptCurMousePos.x - m_ptLastMousePosition.x;
- ptCurMouseDelta.y = ptCurMousePos.y - m_ptLastMousePosition.y;
- // Record current position for next time
- m_ptLastMousePosition = ptCurMousePos;
- }
- else
- {
- // If GetCursorPos() returns false, just set delta to zero
- ptCurMouseDelta.x = 0;
- ptCurMouseDelta.y = 0;
- }
- if( bResetCursorAfterMove && DXUTIsActive() )
- {
- // Set position of camera to center of desktop,
- // so it always has room to move. This is very useful
- // if the cursor is hidden. If this isn't done and cursor is hidden,
- // then invisible cursor will hit the edge of the screen
- // and the user can't tell what happened
- POINT ptCenter;
- // Get the center of the current monitor
- MONITORINFO mi;
- mi.cbSize = sizeof(MONITORINFO);
- DXUTGetMonitorInfo( DXUTMonitorFromWindow(DXUTGetHWND(),MONITOR_DEFAULTTONEAREST), &mi );
- ptCenter.x = (mi.rcMonitor.left + mi.rcMonitor.right) / 2;
- ptCenter.y = (mi.rcMonitor.top + mi.rcMonitor.bottom) / 2;
- SetCursorPos( ptCenter.x, ptCenter.y );
- m_ptLastMousePosition = ptCenter;
- }
- // Smooth the relative mouse data over a few frames so it isn't
- // jerky when moving slowly at low frame rates.
- float fPercentOfNew = 1.0f / m_fFramesToSmoothMouseData;
- float fPercentOfOld = 1.0f - fPercentOfNew;
- m_vMouseDelta.x = m_vMouseDelta.x*fPercentOfOld + ptCurMouseDelta.x*fPercentOfNew;
- m_vMouseDelta.y = m_vMouseDelta.y*fPercentOfOld + ptCurMouseDelta.y*fPercentOfNew;
- }
- if( bGetGamepadInput )
- {
- m_vGamePadLeftThumb = D3DXVECTOR3(0,0,0);
- m_vGamePadRightThumb = D3DXVECTOR3(0,0,0);
- // Get controller state
- for( DWORD iUserIndex=0; iUserIndex<DXUT_MAX_CONTROLLERS; iUserIndex++ )
- {
- DXUTGetGamepadState( iUserIndex, &m_GamePad[iUserIndex], true, true );
- // Mark time if the controller is in a non-zero state
- if( m_GamePad[iUserIndex].wButtons ||
- m_GamePad[iUserIndex].sThumbLX || m_GamePad[iUserIndex].sThumbLX ||
- m_GamePad[iUserIndex].sThumbRX || m_GamePad[iUserIndex].sThumbRY ||
- m_GamePad[iUserIndex].bLeftTrigger || m_GamePad[iUserIndex].bRightTrigger )
- {
- m_GamePadLastActive[iUserIndex] = DXUTGetTime();
- }
- }
- // Find out which controller was non-zero last
- int iMostRecentlyActive = -1;
- double fMostRecentlyActiveTime = 0.0f;
- for( DWORD iUserIndex=0; iUserIndex<DXUT_MAX_CONTROLLERS; iUserIndex++ )
- {
- if( m_GamePadLastActive[iUserIndex] > fMostRecentlyActiveTime )
- {
- fMostRecentlyActiveTime = m_GamePadLastActive[iUserIndex];
- iMostRecentlyActive = iUserIndex;
- }
- }
- // Use the most recent non-zero controller if its connected
- if( iMostRecentlyActive >= 0 && m_GamePad[iMostRecentlyActive].bConnected )
- {
- m_vGamePadLeftThumb.x = m_GamePad[iMostRecentlyActive].fThumbLX;
- m_vGamePadLeftThumb.y = 0.0f;
- m_vGamePadLeftThumb.z = m_GamePad[iMostRecentlyActive].fThumbLY;
- m_vGamePadRightThumb.x = m_GamePad[iMostRecentlyActive].fThumbRX;
- m_vGamePadRightThumb.y = 0.0f;
- m_vGamePadRightThumb.z = m_GamePad[iMostRecentlyActive].fThumbRY;
- }
- }
- }
- //--------------------------------------------------------------------------------------
- // Figure out the velocity based on keyboard input & drag if any
- //--------------------------------------------------------------------------------------
- void CBaseCamera::UpdateVelocity( float fElapsedTime )
- {
- D3DXMATRIX mRotDelta;
- D3DXVECTOR2 vGamePadRightThumb = D3DXVECTOR2(m_vGamePadRightThumb.x, -m_vGamePadRightThumb.z);
- m_vRotVelocity = m_vMouseDelta * m_fRotationScaler + vGamePadRightThumb * 0.02f;
- D3DXVECTOR3 vAccel = m_vKeyboardDirection + m_vGamePadLeftThumb;
- // Normalize vector so if moving 2 dirs (left & forward),
- // the camera doesn't move faster than if moving in 1 dir
- D3DXVec3Normalize( &vAccel, &vAccel );
- // Scale the acceleration vector
- vAccel *= m_fMoveScaler;
- if( m_bMovementDrag )
- {
- // Is there any acceleration this frame?
- if( D3DXVec3LengthSq( &vAccel ) > 0 )
- {
- // If so, then this means the user has pressed a movement key
- // so change the velocity immediately to acceleration
- // upon keyboard input. This isn't normal physics
- // but it will give a quick response to keyboard input
- m_vVelocity = vAccel;
- m_fDragTimer = m_fTotalDragTimeToZero;
- m_vVelocityDrag = vAccel / m_fDragTimer;
- }
- else
- {
- // If no key being pressed, then slowly decrease velocity to 0
- if( m_fDragTimer > 0 )
- {
- // Drag until timer is <= 0
- m_vVelocity -= m_vVelocityDrag * fElapsedTime;
- m_fDragTimer -= fElapsedTime;
- }
- else
- {
- // Zero velocity
- m_vVelocity = D3DXVECTOR3(0,0,0);
- }
- }
- }
- else
- {
- // No drag, so immediately change the velocity
- m_vVelocity = vAccel;
- }
- }