📄 dxutmisc.cpp
字号:
//--------------------------------------------------------------------------------------
// File: DXUTMisc.cpp
//
// Shortcut macros and functions for using DX objects
//
// Copyright (c) Microsoft Corporation. All rights reserved
//--------------------------------------------------------------------------------------
#include "dxut.h"
#include <xinput.h>
#define DXUT_GAMEPAD_TRIGGER_THRESHOLD 30
#undef min // use __min instead
#undef max // use __max instead
CDXUTTimer* WINAPI DXUTGetGlobalTimer()
{
// Using an accessor function gives control of the construction order
static CDXUTTimer timer;
return &timer;
}
//--------------------------------------------------------------------------------------
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;
}
//--------------------------------------------------------------------------------------
float CDXUTTimer::GetElapsedTime()
{
LARGE_INTEGER qwTime = GetAdjustedCurrentTime();
double fElapsedTime = (float) ((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 (float)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 the string for the given D3DFORMAT.
//--------------------------------------------------------------------------------------
LPCWSTR WINAPI DXUTD3DFormatToString( D3DFORMAT format, bool bWithPrefix )
{
WCHAR* pstr = NULL;
switch( format )
{
case D3DFMT_UNKNOWN: pstr = L"D3DFMT_UNKNOWN"; break;
case D3DFMT_R8G8B8: pstr = L"D3DFMT_R8G8B8"; break;
case D3DFMT_A8R8G8B8: pstr = L"D3DFMT_A8R8G8B8"; break;
case D3DFMT_X8R8G8B8: pstr = L"D3DFMT_X8R8G8B8"; break;
case D3DFMT_R5G6B5: pstr = L"D3DFMT_R5G6B5"; break;
case D3DFMT_X1R5G5B5: pstr = L"D3DFMT_X1R5G5B5"; break;
case D3DFMT_A1R5G5B5: pstr = L"D3DFMT_A1R5G5B5"; break;
case D3DFMT_A4R4G4B4: pstr = L"D3DFMT_A4R4G4B4"; break;
case D3DFMT_R3G3B2: pstr = L"D3DFMT_R3G3B2"; break;
case D3DFMT_A8: pstr = L"D3DFMT_A8"; break;
case D3DFMT_A8R3G3B2: pstr = L"D3DFMT_A8R3G3B2"; break;
case D3DFMT_X4R4G4B4: pstr = L"D3DFMT_X4R4G4B4"; break;
case D3DFMT_A2B10G10R10: pstr = L"D3DFMT_A2B10G10R10"; break;
case D3DFMT_A8B8G8R8: pstr = L"D3DFMT_A8B8G8R8"; break;
case D3DFMT_X8B8G8R8: pstr = L"D3DFMT_X8B8G8R8"; break;
case D3DFMT_G16R16: pstr = L"D3DFMT_G16R16"; break;
case D3DFMT_A2R10G10B10: pstr = L"D3DFMT_A2R10G10B10"; break;
case D3DFMT_A16B16G16R16: pstr = L"D3DFMT_A16B16G16R16"; break;
case D3DFMT_A8P8: pstr = L"D3DFMT_A8P8"; break;
case D3DFMT_P8: pstr = L"D3DFMT_P8"; break;
case D3DFMT_L8: pstr = L"D3DFMT_L8"; break;
case D3DFMT_A8L8: pstr = L"D3DFMT_A8L8"; break;
case D3DFMT_A4L4: pstr = L"D3DFMT_A4L4"; break;
case D3DFMT_V8U8: pstr = L"D3DFMT_V8U8"; break;
case D3DFMT_L6V5U5: pstr = L"D3DFMT_L6V5U5"; break;
case D3DFMT_X8L8V8U8: pstr = L"D3DFMT_X8L8V8U8"; break;
case D3DFMT_Q8W8V8U8: pstr = L"D3DFMT_Q8W8V8U8"; break;
case D3DFMT_V16U16: pstr = L"D3DFMT_V16U16"; break;
case D3DFMT_A2W10V10U10: pstr = L"D3DFMT_A2W10V10U10"; break;
case D3DFMT_UYVY: pstr = L"D3DFMT_UYVY"; break;
case D3DFMT_YUY2: pstr = L"D3DFMT_YUY2"; break;
case D3DFMT_DXT1: pstr = L"D3DFMT_DXT1"; break;
case D3DFMT_DXT2: pstr = L"D3DFMT_DXT2"; break;
case D3DFMT_DXT3: pstr = L"D3DFMT_DXT3"; break;
case D3DFMT_DXT4: pstr = L"D3DFMT_DXT4"; break;
case D3DFMT_DXT5: pstr = L"D3DFMT_DXT5"; break;
case D3DFMT_D16_LOCKABLE: pstr = L"D3DFMT_D16_LOCKABLE"; break;
case D3DFMT_D32: pstr = L"D3DFMT_D32"; break;
case D3DFMT_D15S1: pstr = L"D3DFMT_D15S1"; break;
case D3DFMT_D24S8: pstr = L"D3DFMT_D24S8"; break;
case D3DFMT_D24X8: pstr = L"D3DFMT_D24X8"; break;
case D3DFMT_D24X4S4: pstr = L"D3DFMT_D24X4S4"; break;
case D3DFMT_D16: pstr = L"D3DFMT_D16"; break;
case D3DFMT_L16: pstr = L"D3DFMT_L16"; break;
case D3DFMT_VERTEXDATA: pstr = L"D3DFMT_VERTEXDATA"; break;
case D3DFMT_INDEX16: pstr = L"D3DFMT_INDEX16"; break;
case D3DFMT_INDEX32: pstr = L"D3DFMT_INDEX32"; break;
case D3DFMT_Q16W16V16U16: pstr = L"D3DFMT_Q16W16V16U16"; break;
case D3DFMT_MULTI2_ARGB8: pstr = L"D3DFMT_MULTI2_ARGB8"; break;
case D3DFMT_R16F: pstr = L"D3DFMT_R16F"; break;
case D3DFMT_G16R16F: pstr = L"D3DFMT_G16R16F"; break;
case D3DFMT_A16B16G16R16F: pstr = L"D3DFMT_A16B16G16R16F"; break;
case D3DFMT_R32F: pstr = L"D3DFMT_R32F"; break;
case D3DFMT_G32R32F: pstr = L"D3DFMT_G32R32F"; break;
case D3DFMT_A32B32G32R32F: pstr = L"D3DFMT_A32B32G32R32F"; break;
case D3DFMT_CxV8U8: pstr = L"D3DFMT_CxV8U8"; break;
default: pstr = L"Unknown format"; break;
}
if( bWithPrefix || wcsstr( pstr, L"D3DFMT_" )== NULL )
return pstr;
else
return pstr + lstrlen( L"D3DFMT_" );
}
//--------------------------------------------------------------------------------------
// Returns the string for the given DXGI_FORMAT.
//--------------------------------------------------------------------------------------
LPCWSTR WINAPI DXUTDXGIFormatToString( DXGI_FORMAT format, bool bWithPrefix )
{
WCHAR* pstr = NULL;
switch( format )
{
case DXGI_FORMAT_R32G32B32A32_TYPELESS: pstr = L"DXGI_FORMAT_R32G32B32A32_TYPELESS"; break;
case DXGI_FORMAT_R32G32B32A32_FLOAT: pstr = L"DXGI_FORMAT_R32G32B32A32_FLOAT"; break;
case DXGI_FORMAT_R32G32B32A32_UINT: pstr = L"DXGI_FORMAT_R32G32B32A32_UINT"; break;
case DXGI_FORMAT_R32G32B32A32_SINT: pstr = L"DXGI_FORMAT_R32G32B32A32_SINT"; break;
case DXGI_FORMAT_R32G32B32_TYPELESS: pstr = L"DXGI_FORMAT_R32G32B32_TYPELESS"; break;
case DXGI_FORMAT_R32G32B32_FLOAT: pstr = L"DXGI_FORMAT_R32G32B32_FLOAT"; break;
case DXGI_FORMAT_R32G32B32_UINT: pstr = L"DXGI_FORMAT_R32G32B32_UINT"; break;
case DXGI_FORMAT_R32G32B32_SINT: pstr = L"DXGI_FORMAT_R32G32B32_SINT"; break;
case DXGI_FORMAT_R16G16B16A16_TYPELESS: pstr = L"DXGI_FORMAT_R16G16B16A16_TYPELESS"; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -