// TAGRELEASE: PUBLIC #pragma once #include #include #include #include struct DeviceCreationParameters { bool startMaximized; bool startFullscreen; int backBufferWidth; int backBufferHeight; int refreshRate; int swapChainBufferCount; DXGI_FORMAT swapChainFormat; DXGI_FORMAT depthStencilFormat; DXGI_USAGE swapChainUsage; int swapChainSampleCount; int swapChainSampleQuality; UINT createDeviceFlags; D3D_DRIVER_TYPE driverType; D3D_FEATURE_LEVEL featureLevel; // For use in the case of multiple adapters. If this is non-null, device creation will try to match // the given string against an adapter name. If the specified string exists as a sub-string of the // adapter name, the device and window will be created on that adapter. Case sensitive. const WCHAR* adapterNameSubstring; DeviceCreationParameters() : startMaximized(false) , startFullscreen(false) , backBufferWidth(1280) , backBufferHeight(720) , refreshRate(0) , swapChainBufferCount(1) , swapChainFormat(DXGI_FORMAT_R8G8B8A8_UNORM) , depthStencilFormat(DXGI_FORMAT_D24_UNORM_S8_UINT) , swapChainUsage(DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT) , swapChainSampleCount(1) , swapChainSampleQuality(0) , createDeviceFlags(0) , driverType(D3D_DRIVER_TYPE_HARDWARE) , featureLevel(D3D_FEATURE_LEVEL_11_0) , adapterNameSubstring(L"") { } }; #pragma warning(push) #pragma warning(disable: 4100) // unreferenced formal parameter class IVisualController { private: bool m_Enabled; public: IVisualController() : m_Enabled(true) { } virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return 1; } virtual void Render(ID3D11Device* pDevice, ID3D11DeviceContext* pDeviceContext, ID3D11RenderTargetView* pRTV, ID3D11DepthStencilView* pDSV) { } virtual void Animate(double fElapsedTimeSeconds) { } virtual HRESULT DeviceCreated(ID3D11Device* pDevice) { return S_OK; } virtual void DeviceDestroyed() { } virtual void BackBufferResized(ID3D11Device* pDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc) { } virtual void EnableController() { m_Enabled = true; } virtual void DisableController() { m_Enabled = false; } virtual bool IsEnabled() { return m_Enabled; } }; #pragma warning(pop) class DeviceManager { public: enum WindowState { kWindowNone, kWindowNormal, kWindowMinimized, kWindowMaximized, kWindowFullscreen }; protected: ID3D11Device* m_Device; ID3D11DeviceContext* m_ImmediateContext; IDXGISwapChain* m_SwapChain; ID3D11RenderTargetView* m_BackBufferRTV; ID3D11Texture2D* m_DepthStencilBuffer; ID3D11DepthStencilView* m_DepthStencilDSV; DXGI_SWAP_CHAIN_DESC m_SwapChainDesc; D3D11_TEXTURE2D_DESC m_DepthStencilDesc; bool m_IsNvidia; HWND m_hWnd; std::list m_vControllers; std::wstring m_WindowTitle; double m_FixedFrameInterval; UINT m_SyncInterval; std::list m_vFrameTimes; double m_AverageFrameTime; double m_AverageTimeUpdateInterval; bool m_InSizingModalLoop; SIZE m_NewWindowSize; private: HRESULT CreateRenderTargetAndDepthStencil(); void ResizeSwapChain(); public: DeviceManager() : m_Device(NULL) , m_ImmediateContext(NULL) , m_SwapChain(NULL) , m_BackBufferRTV(NULL) , m_DepthStencilBuffer(NULL) , m_DepthStencilDSV(NULL) , m_IsNvidia(false) , m_hWnd(NULL) , m_WindowTitle(L"") , m_FixedFrameInterval(-1) , m_SyncInterval(0) , m_AverageFrameTime(0) , m_AverageTimeUpdateInterval(0.5) , m_InSizingModalLoop(false) { } virtual ~DeviceManager() { Shutdown(); } virtual HRESULT CreateWindowDeviceAndSwapChain(const DeviceCreationParameters& params, std::wstring windowTitle); virtual HRESULT ChangeBackBufferFormat(DXGI_FORMAT format, UINT sampleCount); virtual HRESULT ResizeWindow(int width, int height); virtual HRESULT EnterFullscreenMode(int width = 0, int height = 0); virtual HRESULT LeaveFullscreenMode(int windowWidth = 0, int windowHeight = 0); virtual HRESULT ToggleFullscreen(); virtual void Shutdown(); virtual void MessageLoop(); virtual LRESULT MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); virtual void Render(); virtual void Animate(double fElapsedTimeSeconds); virtual void DeviceCreated(); virtual void DeviceDestroyed(); virtual void BackBufferResized(); void AddControllerToFront(IVisualController* pController); void AddControllerToBack(IVisualController* pController); void RemoveController(IVisualController* pController); void SetFixedFrameInterval(double seconds) { m_FixedFrameInterval = seconds; } void DisableFixedFrameInterval() { m_FixedFrameInterval = -1; } bool IsNvidia() const { return m_IsNvidia; } HWND GetHWND() { return m_hWnd; } ID3D11Device* GetDevice() { return m_Device; } WindowState GetWindowState(); bool GetVsyncEnabled() { return m_SyncInterval > 0; } void SetVsyncEnabled(bool enabled) { m_SyncInterval = enabled ? 1 : 0; } HRESULT GetDisplayResolution(int& width, int& height); IDXGIAdapter* GetDXGIAdapter(); double GetAverageFrameTime() { return m_AverageFrameTime; } void SetAverageTimeUpdateInterval(double value) { m_AverageTimeUpdateInterval = value; } }; DeviceManager* GetDeviceManager();