From 3fcb8c26bf053b3fd83e022c78abb4544867135d Mon Sep 17 00:00:00 2001 From: Danilo Date: Fri, 26 Apr 2024 10:13:00 -0300 Subject: [PATCH] =?UTF-8?q?Implementa=C3=A7=C3=B5es=20em=20PresentationPar?= =?UTF-8?q?ameters?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- framework/enums.hpp | 7 + framework/game/gdevicemanager.hpp | 8 +- framework/graphics/presentparams.hpp | 19 +- framework/graphics/swapchain.hpp | 2 +- framework/platform/adapter-dx.cpp | 10 +- framework/platform/adapter-dx.hpp | 4 +- framework/platform/device-dx.cpp | 243 ++++++++++---------- framework/platform/device-dx.hpp | 16 +- framework/platform/gdeviceinfo-dx.hpp | 3 +- framework/platform/gdevicemanager-dx.cpp | 106 ++++++--- framework/platform/gdevicemanager-dx.hpp | 24 +- framework/platform/presentparameters-dx.hpp | 49 ++++ framework/platform/swapchain-dx.cpp | 26 +-- framework/platform/swapchain-dx.hpp | 2 +- 14 files changed, 299 insertions(+), 220 deletions(-) create mode 100644 framework/platform/presentparameters-dx.hpp diff --git a/framework/enums.hpp b/framework/enums.hpp index d807eb2..2b27ff4 100644 --- a/framework/enums.hpp +++ b/framework/enums.hpp @@ -444,6 +444,13 @@ namespace xna { Unknown, }; + enum class SwapEffect { + Discard, + Sequential, + FlipSequential, + FlipDiscard + }; + enum class TextureAddressMode { Wrap, Mirror, diff --git a/framework/game/gdevicemanager.hpp b/framework/game/gdevicemanager.hpp index bbbc540..58ce364 100644 --- a/framework/game/gdevicemanager.hpp +++ b/framework/game/gdevicemanager.hpp @@ -1,9 +1,7 @@ #ifndef XNA_GAME_GRAPHICSDEVICEMANAGER_HPP #define XNA_GAME_GRAPHICSDEVICEMANAGER_HPP -#include "../types.hpp" -#include "../csharp/timespan.hpp" -#include "../forward.hpp" +#include "../default.hpp" namespace xna { class IGraphicsDeviceManager { @@ -11,13 +9,13 @@ namespace xna { virtual ~IGraphicsDeviceManager(){} virtual void ApplyChanges() = 0; virtual bool Initialize() = 0; - virtual void ToggleFullScreen() = 0; + virtual bool ToggleFullScreen() = 0; virtual Int PreferredBackBufferWidth() const = 0; virtual Int PreferredBackBufferHeight() const = 0; virtual void PreferredBackBufferWidth(Int value) = 0; virtual void PreferredBackBufferHeight(Int value) = 0; protected: - virtual void CreateDevice(GraphicsDeviceInformation const& info) = 0; + virtual bool CreateDevice() = 0; virtual void ChangeDevice() = 0; }; } diff --git a/framework/graphics/presentparams.hpp b/framework/graphics/presentparams.hpp index 3230467..86a4b0b 100644 --- a/framework/graphics/presentparams.hpp +++ b/framework/graphics/presentparams.hpp @@ -4,18 +4,13 @@ #include "../default.hpp" namespace xna { - class PresentationParameters { - public: - Int BackBufferWidth{ 0 }; - Int BackBufferHeight{ 0 }; - SurfaceFormat BackBufferFormat{ SurfaceFormat::Color }; - DepthFormat DepthStencilFormat{ DepthFormat::None }; - Int MultiSampleCount{ 0 }; - xna::DisplayOrientation DisplayOrientation{ xna::DisplayOrientation::Default }; - PresentInterval PresentationInterval{ PresentInterval::Default }; - xna::RenderTargetUsage RenderTargetUsage{ xna::RenderTargetUsage::DiscardContents }; - intptr_t DeviceWindowHandle{ 0 }; - bool IsFullScreen{ false }; + class IPresentationParameters { + virtual Uint BackBufferWidth() const = 0; + virtual Uint BackBufferHeight() const = 0; + virtual SurfaceFormat BackBufferFormat() const = 0; + virtual SwapEffect PresentationSwapEffect() const = 0; + virtual intptr_t DeviceWindowHandle() const = 0; + virtual bool IsFullScreen() const = 0; }; } diff --git a/framework/graphics/swapchain.hpp b/framework/graphics/swapchain.hpp index 0211166..5ec0a48 100644 --- a/framework/graphics/swapchain.hpp +++ b/framework/graphics/swapchain.hpp @@ -8,7 +8,7 @@ namespace xna { class ISwapChain { public: virtual ~ISwapChain() {} - virtual bool Initialize(GameWindow const& gameWindow, xna_error_nullarg) = 0; + virtual bool Initialize(xna_error_nullarg) = 0; }; } diff --git a/framework/platform/adapter-dx.cpp b/framework/platform/adapter-dx.cpp index 7750a59..148461e 100644 --- a/framework/platform/adapter-dx.cpp +++ b/framework/platform/adapter-dx.cpp @@ -170,7 +170,7 @@ namespace xna { if (dxadapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) { const auto currentSurface = static_cast(f); - DXGI_FORMAT format = GraphicsAdapter::ToDXGI(currentSurface); + DXGI_FORMAT format = GraphicsAdapter::ConvertSurfaceToDXGIFORMAT(currentSurface); UINT numModes = 0; pOutput->GetDisplayModeList(format, 0, &numModes, nullptr); @@ -201,7 +201,7 @@ namespace xna { UINT bufferOffset = 0; if (dxadapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { - DXGI_FORMAT format = GraphicsAdapter::ToDXGI(surfaceFormat); + DXGI_FORMAT format = GraphicsAdapter::ConvertSurfaceToDXGIFORMAT(surfaceFormat); UINT numModes = 0; @@ -263,7 +263,7 @@ namespace xna { if (adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) { const auto currentSurface = static_cast(f); - DXGI_FORMAT format = GraphicsAdapter::ToDXGI(currentSurface); + DXGI_FORMAT format = GraphicsAdapter::ConvertSurfaceToDXGIFORMAT(currentSurface); UINT num = 0; pOutput->GetDisplayModeList(format, 0, &num, nullptr); @@ -292,14 +292,14 @@ namespace xna { description._scaling = static_cast(modedesc.Scaling); description._scanlineOrdering = static_cast(modedesc.ScanlineOrdering); - if (pDisplay && pDisplay->_width == modedesc.Width && pDisplay->_height == modedesc.Height && pDisplay->_format == GraphicsAdapter::ToSurface(modedesc.Format)) { + if (pDisplay && pDisplay->_width == modedesc.Width && pDisplay->_height == modedesc.Height && pDisplay->_format == GraphicsAdapter::ConvertDXGIFORMATToSurface(modedesc.Format)) { pDisplay->_descriptions.push_back(description); } else { pDisplay = New(); pDisplay->_width = modedesc.Width; pDisplay->_height = modedesc.Height; - pDisplay->_format = GraphicsAdapter::ToSurface(modedesc.Format); + pDisplay->_format = GraphicsAdapter::ConvertDXGIFORMATToSurface(modedesc.Format); pDisplay->_descriptions.push_back(description); displayList.push_back(pDisplay); } diff --git a/framework/platform/adapter-dx.hpp b/framework/platform/adapter-dx.hpp index df74c35..9ed8eec 100644 --- a/framework/platform/adapter-dx.hpp +++ b/framework/platform/adapter-dx.hpp @@ -41,7 +41,7 @@ namespace xna { PDisplayMode _currentDisplayMode = nullptr; public: - static constexpr DXGI_FORMAT ToDXGI(SurfaceFormat format) + static constexpr DXGI_FORMAT ConvertSurfaceToDXGIFORMAT(SurfaceFormat format) { switch (format) { @@ -90,7 +90,7 @@ namespace xna { } } - static constexpr SurfaceFormat ToSurface(DXGI_FORMAT format) { + static constexpr SurfaceFormat ConvertDXGIFORMATToSurface(DXGI_FORMAT format) { switch (format) { case DXGI_FORMAT_B8G8R8A8_UNORM: diff --git a/framework/platform/device-dx.cpp b/framework/platform/device-dx.cpp index 97848fe..86bd563 100644 --- a/framework/platform/device-dx.cpp +++ b/framework/platform/device-dx.cpp @@ -9,36 +9,112 @@ #include "gdevicemanager-dx.hpp" namespace xna { - GraphicsDevice::GraphicsDevice() { - _blendState = BlendState::NonPremultiplied(); - _adapter = GraphicsAdapter::DefaultAdapter(); - _adapter->CurrentDisplayMode(SurfaceFormat::Color, GraphicsDeviceManager::DefaultBackBufferWidth, GraphicsDeviceManager::DefaultBackBufferHeight); - } + GraphicsDevice::GraphicsDevice() { + _adapter = GraphicsAdapter::DefaultAdapter(); + _adapter->CurrentDisplayMode(SurfaceFormat::Color, GraphicsDeviceManager::DefaultBackBufferWidth, GraphicsDeviceManager::DefaultBackBufferHeight); + } - GraphicsDevice::GraphicsDevice(GraphicsDeviceInformation const& info) { - _adapter = info.Adapter(); - _presentParameters = info.PresentationParameters(); - _adapter->CurrentDisplayMode(_presentParameters.BackBufferFormat, _presentParameters.BackBufferWidth, _presentParameters.BackBufferHeight); - } + GraphicsDevice::GraphicsDevice(GraphicsDeviceInformation const& info) { + _adapter = info.Adapter(); + _presentationParameters = info.PresentationParameters(); + _adapter->CurrentDisplayMode(_presentationParameters.backBufferFormat, _presentationParameters.backBufferWidth, _presentationParameters.backBufferHeight); + } - bool GraphicsDevice::Initialize(GameWindow& gameWindow) { - if (_factory) { - _factory->Release(); - _factory = nullptr; - } + bool GraphicsDevice::Initialize(GameWindow& gameWindow) { + reset(); + + if (!createDevice()) return false; - auto hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&_factory); + auto hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&_factory); + if (FAILED(hr)) return false; - if (FAILED(hr)) { - return false; - } + const auto bounds = gameWindow.ClientBounds(); - if (_blendState == nullptr) - _blendState = BlendState::NonPremultiplied(); - _blendState->Bind(this); + _viewport = xna::Viewport(0.0F, 0.0F, + static_cast(bounds.Width), + static_cast(bounds.Height), + 0.0F, 1.F); - _createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; + COLORREF color = gameWindow.Color(); + _backgroundColor[0] = GetRValue(color) / 255.0f; + _backgroundColor[1] = GetGValue(color) / 255.0f; + _backgroundColor[2] = GetBValue(color) / 255.0f; + _backgroundColor[3] = 1.0f; + _swapChain = New(this); + _swapChain->Initialize(); + + hr = _factory->MakeWindowAssociation(gameWindow.WindowHandle(), DXGI_MWA_NO_ALT_ENTER); + if (FAILED(hr)) return false; + + _renderTarget2D = New(); + if (!_renderTarget2D->Initialize(*this)) return false; + + _renderTarget2D->Apply(*this); + + D3D11_VIEWPORT view{}; + view.TopLeftX = _viewport.X; + view.TopLeftY = _viewport.Y; + view.Width = _viewport.Width; + view.Height = _viewport.Height; + view.MinDepth = _viewport.MinDetph; + view.MaxDepth = _viewport.MaxDepth; + + _context->RSSetViewports(1, &view); + + _blendState = BlendState::NonPremultiplied(); + _blendState->Bind(this); + _blendState->Apply(); + + return true; + } + + bool GraphicsDevice::Present() { + const auto result = _swapChain->Present(_usevsync); + _context->OMSetRenderTargets(1, &_renderTarget2D->_renderTargetView, nullptr); + + return result; + } + + bool GraphicsDevice::createDevice() { +#if _DEBUG + _createDeviceFlags |= D3D11_CREATE_DEVICE_FLAG::D3D11_CREATE_DEVICE_DEBUG; +#endif + + if FAILED( + D3D11CreateDevice( + _adapter->dxadapter, + D3D_DRIVER_TYPE_UNKNOWN, + NULL, + _createDeviceFlags, + NULL, + 0, + D3D11_SDK_VERSION, + &_device, + &_featureLevel, + &_context)) { + + if FAILED(D3D11CreateDevice( + NULL, + D3D_DRIVER_TYPE_WARP, + NULL, + _createDeviceFlags, + NULL, + 0, + D3D11_SDK_VERSION, + &_device, + &_featureLevel, + &_context)) + return false; + + OutputDebugString("---> Usando Adaptador WARP: não há suporte ao D3D11\n"); + } + + return true; + } + + void GraphicsDevice::reset() + { if (_device) { _device->Release(); _device = nullptr; @@ -47,113 +123,30 @@ namespace xna { if (_context) { _context->Release(); _context = nullptr; - } + } - gameWindow.Size(_presentParameters.BackBufferWidth, _presentParameters.BackBufferHeight); - const auto bounds = gameWindow.ClientBounds(); + if (_factory) { + _factory->Release(); + _factory = nullptr; + } - _viewport = xna::Viewport(0.0F, 0.0F, - static_cast(bounds.Width), - static_cast(bounds.Height), - 0.0F, 1.F); - - if (!createDevice()) - return false; - - COLORREF color = gameWindow.Color(); - _backgroundColor[0] = GetRValue(color) / 255.0f; - _backgroundColor[1] = GetGValue(color) / 255.0f; - _backgroundColor[2] = GetBValue(color) / 255.0f; - _backgroundColor[3] = 1.0f; - - if (!_swapChain) - _swapChain = New(this); - - _swapChain->Initialize(gameWindow); - - if FAILED(_factory->MakeWindowAssociation(gameWindow.WindowHandle(), DXGI_MWA_NO_ALT_ENTER)) - return false; - - if (!_renderTarget2D) { - _renderTarget2D = New(); - } - - if (!_renderTarget2D->Initialize(*this)) - return false; - - _renderTarget2D->Apply(*this); - - D3D11_VIEWPORT view{}; - view.TopLeftX = _viewport.X; - view.TopLeftY = _viewport.Y; - view.Width = _viewport.Width; - view.Height = _viewport.Height; - view.MinDepth = _viewport.MinDetph; - view.MaxDepth = _viewport.MaxDepth; - - _context->RSSetViewports(1, &view); - - _blendState->Apply(); - - return true; + _blendState = nullptr; + _swapChain = nullptr; + _renderTarget2D = nullptr; } - bool GraphicsDevice::Present() { - const auto result = _swapChain->Present(_usevsync); - _context->OMSetRenderTargets(1, &_renderTarget2D->_renderTargetView, nullptr); + void GraphicsDevice::Clear() { + _context->ClearRenderTargetView(_renderTarget2D->_renderTargetView, _backgroundColor); + } - return result; - } + void GraphicsDevice::Clear(Color const& color) { + const auto v4 = color.ToVector4(); - bool GraphicsDevice::createDevice() { -#if _DEBUG - _createDeviceFlags |= D3D11_CREATE_DEVICE_FLAG::D3D11_CREATE_DEVICE_DEBUG; -#endif + _backgroundColor[0] = v4.X; + _backgroundColor[1] = v4.Y; + _backgroundColor[2] = v4.Z; + _backgroundColor[3] = v4.W; - if FAILED( - D3D11CreateDevice( - _adapter->dxadapter, - D3D_DRIVER_TYPE_UNKNOWN, - NULL, - _createDeviceFlags, - NULL, - 0, - D3D11_SDK_VERSION, - &_device, - &_featureLevel, - &_context)) { - - if FAILED(D3D11CreateDevice( - NULL, - D3D_DRIVER_TYPE_WARP, - NULL, - _createDeviceFlags, - NULL, - 0, - D3D11_SDK_VERSION, - &_device, - &_featureLevel, - &_context)) - return false; - - OutputDebugString("---> Usando Adaptador WARP: não há suporte ao D3D11\n"); - } - - return true; - } - - void GraphicsDevice::Clear() { - _context->ClearRenderTargetView(_renderTarget2D->_renderTargetView, _backgroundColor); - } - - void GraphicsDevice::Clear(Color const& color) { - const auto v4 = color.ToVector4(); - - _backgroundColor[0] = v4.X; - _backgroundColor[1] = v4.Y; - _backgroundColor[2] = v4.Z; - _backgroundColor[3] = v4.W; - - _context->ClearRenderTargetView(_renderTarget2D->_renderTargetView, _backgroundColor); - } + _context->ClearRenderTargetView(_renderTarget2D->_renderTargetView, _backgroundColor); + } } \ No newline at end of file diff --git a/framework/platform/device-dx.hpp b/framework/platform/device-dx.hpp index b20065b..76eb63e 100644 --- a/framework/platform/device-dx.hpp +++ b/framework/platform/device-dx.hpp @@ -1,16 +1,17 @@ #ifndef XNA_PLATFORM_DEVICE_DX_HPP #define XNA_PLATFORM_DEVICE_DX_HPP +#include "../common/color.hpp" #include "../graphics/device.hpp" #include "../graphics/presentparams.hpp" -#include "adapter-dx.hpp" -#include "gdeviceinfo-dx.hpp" -#include "../common/color.hpp" -#include "window-dx.hpp" #include "../graphics/viewport.hpp" -#include "swapchain-dx.hpp" -#include "dxgi.h" +#include "adapter-dx.hpp" #include "d3d11.h" +#include "dxgi.h" +#include "gdeviceinfo-dx.hpp" +#include "swapchain-dx.hpp" +#include "window-dx.hpp" +#include "presentparameters-dx.hpp" namespace xna { class GraphicsDevice : public IGraphicsDevice { @@ -79,15 +80,16 @@ namespace xna { PRenderTarget2D _renderTarget2D{ nullptr }; PBlendState _blendState{ nullptr }; xna::Viewport _viewport{}; + xna::PresentationParameters _presentationParameters; private: unsigned int _createDeviceFlags{ 0 }; D3D_FEATURE_LEVEL _featureLevel{ D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_11_0 }; float _backgroundColor[4] = { 0, 0, 0, 0 }; - xna::PresentationParameters _presentParameters; bool _usevsync{ true }; bool createDevice(); + void reset(); }; } diff --git a/framework/platform/gdeviceinfo-dx.hpp b/framework/platform/gdeviceinfo-dx.hpp index 92b0e23..0f3f1ef 100644 --- a/framework/platform/gdeviceinfo-dx.hpp +++ b/framework/platform/gdeviceinfo-dx.hpp @@ -4,6 +4,7 @@ #include "../game/gdeviceinfo.hpp" #include "adapter-dx.hpp" #include "window-dx.hpp" +#include "presentparameters-dx.hpp" namespace xna { class GraphicsDeviceInformation : public IGraphicsDeviceInformation { @@ -42,7 +43,7 @@ namespace xna { _window = window; } - private: + public: PGraphicsAdapter _adapter{ nullptr }; xna::GraphicsProfile _profile{xna::GraphicsProfile::Reach}; xna::PresentationParameters _parameters{}; diff --git a/framework/platform/gdevicemanager-dx.cpp b/framework/platform/gdevicemanager-dx.cpp index 001c256..8fa5eed 100644 --- a/framework/platform/gdevicemanager-dx.cpp +++ b/framework/platform/gdevicemanager-dx.cpp @@ -4,39 +4,37 @@ #include "window-dx.hpp" #include "gdeviceinfo-dx.hpp" #include "adapter-dx.hpp" +#include "presentparameters-dx.hpp" namespace xna { GraphicsDeviceManager::GraphicsDeviceManager(Game*& game) : _game(game) { + sptr adp = GraphicsAdapter::DefaultAdapter(); + _information.Adapter(adp); + _information.GraphicsProfile(xna::GraphicsProfile::HiDef); + + PresentationParameters parameters; + parameters.backBufferWidth = _backBufferWidth; + parameters.backBufferHeight = _backBufferHeight; + parameters.backBufferFormat = SurfaceFormat::Color; + parameters.fullscreen = false; + _information.PresentationParameters(parameters); + + if(_game) _information.Window(_game->Window()); } bool GraphicsDeviceManager::Initialize() { - GraphicsDeviceInformation information; + if (!_game) + return false; - auto adp = GraphicsAdapter::DefaultAdapter(); - const PGraphicsAdapter sadp = std::move(adp); - information.Adapter(sadp); - information.GraphicsProfile(xna::GraphicsProfile::HiDef); - - PresentationParameters parameters; - parameters.BackBufferWidth = _backBufferWidth; - parameters.BackBufferHeight = _backBufferHeight; - parameters.BackBufferFormat = SurfaceFormat::Color; - parameters.IsFullScreen = false; - information.PresentationParameters(parameters); - - information.Window(_game->Window()); - - CreateDevice(information); - - return true; + return CreateDevice(); } void GraphicsDeviceManager::ApplyChanges() { } - void GraphicsDeviceManager::ToggleFullScreen() { + bool GraphicsDeviceManager::ToggleFullScreen() { if (!_game || !_game->_graphicsDevice || !_game->_graphicsDevice->_swapChain) - return; + return false; auto& swap = _game->_graphicsDevice->_swapChain; @@ -49,28 +47,66 @@ namespace xna { if (FAILED(hr)) return; - _ifFullScreen = !state; + _isFullScreen = !state; } - void GraphicsDeviceManager::CreateDevice(GraphicsDeviceInformation const& info) { - _device = New(info); - auto window = info.Window(); + void GraphicsDeviceManager::PreferredBackBufferWidth(Int value) { + _backBufferWidth = value; + _isDeviceDirty = true; + } - window->Size(_backBufferWidth, _backBufferHeight); - - if (!window->Create()) { - MessageBox(nullptr, "Falha na criação da janela", "Xna Game Engine", MB_OK); - return; + void GraphicsDeviceManager::PreferredBackBufferHeight(Int value) { + _backBufferHeight = value; + _isDeviceDirty = true; + } + + bool GraphicsDeviceManager::CreateDevice() { + if (_isDeviceDirty) { + _information._parameters.backBufferWidth = _backBufferWidth; + _information._parameters.backBufferHeight = _backBufferHeight; } - - if (!_device->Initialize(*window)) { - MessageBox(nullptr, "Falha na inicialização do dispositivo gráfico", "Xna Game Engine", MB_OK); - return; - } - _game->_graphicsDevice = _device; + initWindow(); + initDevice(); + + return true; } void GraphicsDeviceManager::ChangeDevice() { } + + bool GraphicsDeviceManager::initWindow() + { + auto window = _information.Window(); + + if (!window) { + window = _game->Window(); + _information.Window(window); + } + + window->Size(_backBufferWidth, _backBufferHeight); + + if (!window->Create()) { + MessageBox(nullptr, "Falha na criação da janela", "XN65", MB_OK); + return false; + } + + _information._parameters.windowHandle = window->WindowHandle(); + + return true; + } + + bool GraphicsDeviceManager::initDevice() + { + auto window = _information.Window(); + _device = New(_information); + + if (!_device->Initialize(*window)) { + MessageBox(window->WindowHandle(), "Falha na inicialização do dispositivo gráfico", "XN65", MB_OK); + _device = nullptr; + return false; + } + + _game->_graphicsDevice = _device; + } } \ No newline at end of file diff --git a/framework/platform/gdevicemanager-dx.hpp b/framework/platform/gdevicemanager-dx.hpp index b7c5650..e29c812 100644 --- a/framework/platform/gdevicemanager-dx.hpp +++ b/framework/platform/gdevicemanager-dx.hpp @@ -12,7 +12,7 @@ namespace xna { virtual void ApplyChanges() override; virtual bool Initialize() override; - virtual void ToggleFullScreen() override; + virtual bool ToggleFullScreen() override; virtual constexpr Int PreferredBackBufferWidth() const { return _backBufferWidth; @@ -22,18 +22,11 @@ namespace xna { return _backBufferHeight; } - virtual void PreferredBackBufferWidth(Int value) { - _backBufferWidth = value; - _isDeviceDirty = true; - } - - virtual void PreferredBackBufferHeight(Int value) { - _backBufferHeight = value; - _isDeviceDirty = true; - } + virtual void PreferredBackBufferWidth(Int value); + virtual void PreferredBackBufferHeight(Int value); protected: - virtual void CreateDevice(GraphicsDeviceInformation const& info) override; + virtual bool CreateDevice() override; virtual void ChangeDevice() override; public: @@ -45,8 +38,13 @@ namespace xna { Int _backBufferWidth{ DefaultBackBufferWidth }; Int _backBufferHeight{ DefaultBackBufferHeight }; bool _isDeviceDirty{ false }; - PGraphicsDevice _device; - bool _ifFullScreen{ false }; + PGraphicsDevice _device = nullptr; + bool _isFullScreen{ false }; + GraphicsDeviceInformation _information{}; + + bool initWindow(); + bool initDevice(); + }; } diff --git a/framework/platform/presentparameters-dx.hpp b/framework/platform/presentparameters-dx.hpp new file mode 100644 index 0000000..a084c52 --- /dev/null +++ b/framework/platform/presentparameters-dx.hpp @@ -0,0 +1,49 @@ +#ifndef XNA_PLATFORM_PRESENTPARAMETERS_DX_HPP +#define XNA_PLATFORM_PRESENTPARAMETERS_DX_HPP + +#include "../graphics/presentparams.hpp" +#include "gdevicemanager-dx.hpp" +#include "dxheaders.hpp" + +namespace xna { + class PresentationParameters : public IPresentationParameters { + public: + virtual constexpr Uint BackBufferWidth() const override { + return backBufferWidth; + } + + virtual constexpr Uint BackBufferHeight() const override { + return backBufferHeight; + } + + virtual constexpr SurfaceFormat BackBufferFormat() const override { + return backBufferFormat; + } + + virtual constexpr SwapEffect PresentationSwapEffect() const override { + return swapEffect; + } + + virtual intptr_t DeviceWindowHandle() const override { + return reinterpret_cast(windowHandle); + } + + virtual constexpr bool IsFullScreen() const override { + return fullscreen; + } + + HWND DeviceWindowHWND() const { + return windowHandle; + } + + public: + Uint backBufferWidth { GraphicsDeviceManager::DefaultBackBufferWidth }; + Uint backBufferHeight{ GraphicsDeviceManager::DefaultBackBufferHeight }; + SurfaceFormat backBufferFormat{ SurfaceFormat::Color }; + SwapEffect swapEffect{ SwapEffect::FlipDiscard }; + HWND windowHandle = nullptr; + bool fullscreen{ false }; + }; +} + +#endif \ No newline at end of file diff --git a/framework/platform/swapchain-dx.cpp b/framework/platform/swapchain-dx.cpp index e11d550..2538c3d 100644 --- a/framework/platform/swapchain-dx.cpp +++ b/framework/platform/swapchain-dx.cpp @@ -3,8 +3,8 @@ #include "device-dx.hpp" namespace xna { - static bool internalInit(GraphicsDevice& device, GameWindow const& gameWindow, IDXGISwapChain1*& swapChain, DXGI_SWAP_CHAIN_DESC1 const& desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC const& fdesc) { - if (!device._device || !gameWindow.WindowHandle()) + static bool internalInit(GraphicsDevice& device, HWND windowHandle, IDXGISwapChain1*& swapChain, DXGI_SWAP_CHAIN_DESC1 const& desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC const& fdesc) { + if (!device._device || !windowHandle) return false; if (swapChain) { @@ -27,7 +27,7 @@ namespace xna { dxFactory2->CreateSwapChainForHwnd( device._device, - gameWindow.WindowHandle(), + windowHandle, &desc, &fdesc, nullptr, @@ -37,31 +37,31 @@ namespace xna { return true; } - bool SwapChain::Initialize(GameWindow const& gameWindow, xna_error_ptr_arg) { + bool SwapChain::Initialize(xna_error_ptr_arg) { if (!m_device || !m_device->_device) { xna_error_apply(err, XnaErrorCode::INVALID_OPERATION); return false; } + + const auto parameters = m_device->_presentationParameters; - const auto bounds = gameWindow.ClientBounds(); - - dxDescription.Width = static_cast(bounds.Width); - dxDescription.Height = static_cast(bounds.Height); - dxDescription.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + dxDescription.Width = static_cast(parameters.backBufferWidth); + dxDescription.Height = static_cast(parameters.backBufferHeight); + dxDescription.Format = GraphicsAdapter::ConvertSurfaceToDXGIFORMAT(parameters.backBufferFormat); dxDescription.SampleDesc.Count = 1; dxDescription.SampleDesc.Quality = 0; dxDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; dxDescription.BufferCount = 2; - dxDescription.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + dxDescription.SwapEffect = static_cast(parameters.swapEffect); dxDescription.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; dxDescription.AlphaMode = DXGI_ALPHA_MODE::DXGI_ALPHA_MODE_UNSPECIFIED; dxFullScreenDescription.RefreshRate.Numerator = 60; dxFullScreenDescription.RefreshRate.Denominator = 1; dxFullScreenDescription.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; dxFullScreenDescription.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; - dxFullScreenDescription.Windowed = gameWindow.Mode() != GameWindowMode::Fullscreen; + dxFullScreenDescription.Windowed = !parameters.fullscreen; - return internalInit(*m_device, gameWindow, dxSwapChain, dxDescription, dxFullScreenDescription); + return internalInit(*m_device, parameters.windowHandle, dxSwapChain, dxDescription, dxFullScreenDescription); } bool SwapChain::Initialize(GameWindow const& gameWindow, DXGI_SWAP_CHAIN_DESC1 const& desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC const& fullScreenDesc, xna_error_ptr_arg) @@ -73,7 +73,7 @@ namespace xna { dxDescription = desc; dxFullScreenDescription = fullScreenDesc; - return internalInit(*m_device, gameWindow, dxSwapChain, dxDescription, dxFullScreenDescription); + return internalInit(*m_device, gameWindow.WindowHandle(), dxSwapChain, dxDescription, dxFullScreenDescription); } bool SwapChain::GetBackBuffer(ID3D11Texture2D*& texture2D) { diff --git a/framework/platform/swapchain-dx.hpp b/framework/platform/swapchain-dx.hpp index 95785da..9a12b0b 100644 --- a/framework/platform/swapchain-dx.hpp +++ b/framework/platform/swapchain-dx.hpp @@ -18,7 +18,7 @@ namespace xna { } } - virtual bool Initialize(GameWindow const& gameWindow, xna_error_nullarg) override; + virtual bool Initialize(xna_error_nullarg) override; bool Initialize(GameWindow const& gameWindow, DXGI_SWAP_CHAIN_DESC1 const& desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC const& fullScreenDesc, xna_error_nullarg); bool GetBackBuffer(ID3D11Texture2D*& texture2D);