diff --git a/framework/graphics/rendertarget.hpp b/framework/graphics/rendertarget.hpp index 1a8e6f1..1e8ca1c 100644 --- a/framework/graphics/rendertarget.hpp +++ b/framework/graphics/rendertarget.hpp @@ -9,7 +9,8 @@ namespace xna { public: virtual ~IRenderTarget2D(){} - virtual bool Bind() = 0; + virtual bool Initialize(GraphicsDevice& device) = 0; + virtual bool Apply(GraphicsDevice& device) = 0; }; } diff --git a/framework/graphics/swapchain.hpp b/framework/graphics/swapchain.hpp index 36c9b33..3ba999b 100644 --- a/framework/graphics/swapchain.hpp +++ b/framework/graphics/swapchain.hpp @@ -1,17 +1,14 @@ #ifndef XNA_GRAPHICS_SWAPCHAIN_HPP #define XNA_GRAPHICS_SWAPCHAIN_HPP -#include "../types.hpp" -#include "../enums.hpp" -#include "../forward.hpp" +#include "../default.hpp" #include "../game/window.hpp" namespace xna { class ISwapChain { public: virtual ~ISwapChain() {} - virtual bool Initialize(GameWindow const& gameWindow) = 0; - virtual bool Apply() = 0; + virtual bool Initialize(GraphicsDevice& device, GameWindow const& gameWindow) = 0; }; } diff --git a/framework/platform/adapter-dx.cpp b/framework/platform/adapter-dx.cpp index f16dc29..5661b5d 100644 --- a/framework/platform/adapter-dx.cpp +++ b/framework/platform/adapter-dx.cpp @@ -152,9 +152,9 @@ namespace xna { return static_cast(desc.VendorId); } - static UINT getDisplayModesCount(IDXGIAdapter* adapter) { + static size_t getDisplayModesCount(IDXGIAdapter* adapter) { IDXGIOutput* pOutput = nullptr; - UINT numModes = 0; + size_t numModes = 0; if (adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) { @@ -177,11 +177,14 @@ namespace xna { UDisplayModeCollection GraphicsAdapter::SupportedDisplayModes() const { if (!_adapter) return nullptr; - IDXGIOutput* pOutput = nullptr; - UINT numModes = 0; - UINT totalModes = 0; - const auto totalDisplay = getDisplayModesCount(_adapter); + + if (totalDisplay == 0) + return nullptr; + + IDXGIOutput* pOutput = nullptr; + UINT bufferOffset = 0; + std::vector buffer(totalDisplay); if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { @@ -189,14 +192,15 @@ namespace xna { const auto currentSurface = static_cast(f); DXGI_FORMAT format = GraphicsAdapter::ToDXGI(currentSurface); + UINT numModes = 0; pOutput->GetDisplayModeList(format, 0, &numModes, nullptr); if (numModes == 0) continue; - pOutput->GetDisplayModeList(format, 0, &numModes, buffer.data() + totalModes); + pOutput->GetDisplayModeList(format, 0, &numModes, buffer.data() + bufferOffset); - totalModes += numModes; + bufferOffset += numModes; } } @@ -211,7 +215,7 @@ namespace xna { std::vector displayList; PDisplayMode pDisplay = nullptr; - for (size_t i = 0; i < totalModes; ++i) { + for (size_t i = 0; i < totalDisplay; ++i) { auto& modedesc = buffer[i]; DisplayModeDescription description; diff --git a/framework/platform/device-dx.cpp b/framework/platform/device-dx.cpp index 11e40fb..7b0e584 100644 --- a/framework/platform/device-dx.cpp +++ b/framework/platform/device-dx.cpp @@ -63,23 +63,22 @@ namespace xna { _backgroundColor[3] = 1.0f; if (!_swapChain) - _swapChain = New(this); + _swapChain = New(); - _swapChain->Initialize(gameWindow); - - if (!_swapChain->Apply()) - return false; + _swapChain->Initialize(*this, gameWindow); if FAILED(_factory->MakeWindowAssociation(gameWindow.WindowHandle(), DXGI_MWA_NO_ALT_ENTER)) return false; if (!_renderTarget2D) { - _renderTarget2D = New(this); + _renderTarget2D = New(); } - if (!_renderTarget2D->Bind()) + if (!_renderTarget2D->Initialize(*this)) return false; + _renderTarget2D->Apply(*this); + D3D11_VIEWPORT view{}; view.TopLeftX = _viewport.X; view.TopLeftY = _viewport.Y; diff --git a/framework/platform/device-dx.hpp b/framework/platform/device-dx.hpp index f00f1c2..58e2eca 100644 --- a/framework/platform/device-dx.hpp +++ b/framework/platform/device-dx.hpp @@ -74,6 +74,7 @@ namespace xna { ID3D11Device* _device{ nullptr }; ID3D11DeviceContext* _context{ nullptr }; IDXGIFactory1* _factory = nullptr; + PSwapChain _swapChain{ nullptr }; private: unsigned int _createDeviceFlags{ 0 }; @@ -81,7 +82,6 @@ namespace xna { float _backgroundColor[4] = { 0, 0, 0, 0 }; xna::PresentationParameters _presentParameters; PGraphicsAdapter _adapter{ nullptr }; - PSwapChain _swapChain{ nullptr }; PRenderTarget2D _renderTarget2D{ nullptr }; xna::Viewport _viewport{}; PBlendState _blendState{ nullptr }; diff --git a/framework/platform/displaymode-dx.cpp b/framework/platform/displaymode-dx.cpp index 3f99ac9..5f5e46b 100644 --- a/framework/platform/displaymode-dx.cpp +++ b/framework/platform/displaymode-dx.cpp @@ -1 +1,41 @@ -#include "displaymode-dx.hpp" \ No newline at end of file +#include "displaymode-dx.hpp" + +namespace xna { + std::vector DisplayModeCollection::At(SurfaceFormat format) const + { + std::vector modes; + At(format, modes); + return modes; + } + + void DisplayModeCollection::At(SurfaceFormat format, std::vector& modes) const + { + size_t counter = 0; + + for (size_t i = 0; i < _displayModes.size(); ++i) { + const auto& displayMode = _displayModes[i]; + + if (displayMode->Format() == format) + { + modes.push_back(displayMode); + ++counter; + } + } + + if (!modes.empty()) + modes.resize(counter); + } + + size_t DisplayModeCollection::SurfaceCount(SurfaceFormat format) const + { + size_t counter = 0; + + for (size_t i = 0; i < _displayModes.size(); ++i) { + if (_displayModes[i]->Format() == format) { + ++counter; + } + } + + return counter; + } +} \ No newline at end of file diff --git a/framework/platform/displaymode-dx.hpp b/framework/platform/displaymode-dx.hpp index 0997379..623f193 100644 --- a/framework/platform/displaymode-dx.hpp +++ b/framework/platform/displaymode-dx.hpp @@ -88,40 +88,11 @@ namespace xna { DisplayModeCollection(std::vector const& displayModes) : _displayModes(displayModes) {} - std::vector At(SurfaceFormat format) const { - std::vector modes; - At(format, modes); - return modes; - } + virtual std::vector At(SurfaceFormat format) const override; - void At(SurfaceFormat format, std::vector& modes) const { - size_t counter = 0; + virtual void At(SurfaceFormat format, std::vector& modes) const override; - for (size_t i = 0; i < _displayModes.size(); ++i) { - const auto& displayMode = _displayModes[i]; - - if (displayMode->Format() == format) - { - modes.push_back(displayMode); - ++counter; - } - } - - if (!modes.empty()) - modes.resize(counter); - } - - size_t SurfaceCount(SurfaceFormat format) const { - size_t counter = 0; - - for (size_t i = 0; i < _displayModes.size(); ++i) { - if (_displayModes[i]->Format() == format) { - ++counter; - } - } - - return counter; - } + virtual size_t SurfaceCount(SurfaceFormat format) const override; std::vector operator[](SurfaceFormat format) const { return At(format); diff --git a/framework/platform/rendertarget-dx.cpp b/framework/platform/rendertarget-dx.cpp index 126b7f8..564a58d 100644 --- a/framework/platform/rendertarget-dx.cpp +++ b/framework/platform/rendertarget-dx.cpp @@ -4,27 +4,31 @@ #include "device-dx.hpp" namespace xna { - RenderTarget2D::RenderTarget2D(GraphicsDevice* device) { - _device = device; - } + bool RenderTarget2D::Initialize(GraphicsDevice& device) { + if (!device._device) + return false; - bool RenderTarget2D::Bind() { if (_texture2D) { _texture2D->Release(); _texture2D = nullptr; } - if (!_device->GetSwapChainBackBuffer(_texture2D)) + if (!device._swapChain->GetBackBuffer(_texture2D)) return false; - auto& device = _device->_device; + auto& dxdevice = device._device; - if FAILED(device->CreateRenderTargetView(_texture2D, NULL, &_renderTargetView)) - return false; + const auto hr = dxdevice->CreateRenderTargetView(_texture2D, NULL, &_renderTargetView); - auto& context = _device->_context; - context->OMSetRenderTargets(1, &_renderTargetView, nullptr); + if (FAILED(hr)) + return false; return true; } + + bool RenderTarget2D::Apply(GraphicsDevice& device) { + auto& context = device._context; + context->OMSetRenderTargets(1, &_renderTargetView, nullptr); + return true; + } } \ No newline at end of file diff --git a/framework/platform/rendertarget-dx.hpp b/framework/platform/rendertarget-dx.hpp index 8bec094..81493c3 100644 --- a/framework/platform/rendertarget-dx.hpp +++ b/framework/platform/rendertarget-dx.hpp @@ -9,8 +9,6 @@ namespace xna { class RenderTarget2D : public IRenderTarget2D, public Texture2D { public: - RenderTarget2D(GraphicsDevice* device); - virtual ~RenderTarget2D() override { if (_renderTargetView) { _renderTargetView->Release(); @@ -18,12 +16,12 @@ namespace xna { } } - virtual bool Bind() override; + virtual bool Initialize(GraphicsDevice& device) override; + virtual bool Apply(GraphicsDevice& device) override; public: ID3D11RenderTargetView* _renderTargetView = nullptr; D3D11_RENDER_TARGET_VIEW_DESC _renderTargetDesc{}; - GraphicsDevice* _device{ nullptr }; }; } diff --git a/framework/platform/swapchain-dx.cpp b/framework/platform/swapchain-dx.cpp index 463548b..f119873 100644 --- a/framework/platform/swapchain-dx.cpp +++ b/framework/platform/swapchain-dx.cpp @@ -1,53 +1,66 @@ #include "swapchain-dx.hpp" -#include "../graphics/device.hpp" #include "adapter-dx.hpp" #include "device-dx.hpp" namespace xna { - SwapChain::SwapChain(GraphicsDevice* device){ - _device = device; - } + 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()) + return false; + + if (swapChain) { + swapChain->Release(); + swapChain = nullptr; + } - bool SwapChain::Initialize(GameWindow const& gameWindow) { - const auto bounds = gameWindow.ClientBounds(); + auto adapter = device.Adapter(); + auto dxAdapter = adapter->_adapter; + + IDXGIFactory1* dxFactory1 = nullptr; + auto hr = dxAdapter->GetParent(IID_IDXGIFactory1, (void**)&dxFactory1); + + if (FAILED(hr)) return false; + + IDXGIFactory2* dxFactory2 = nullptr; + hr = dxFactory1->QueryInterface(IID_IDXGIFactory2, (void**)&dxFactory2); + + if (FAILED(hr)) return false; + + dxFactory2->CreateSwapChainForHwnd( + device._device, + gameWindow.WindowHandle(), + &desc, + &fdesc, + nullptr, + &swapChain); - _swapDescription.BufferDesc.Width = static_cast(bounds.Width); - _swapDescription.BufferDesc.Height = static_cast(bounds.Height); - _swapDescription.BufferDesc.RefreshRate.Numerator = 60; - _swapDescription.BufferDesc.RefreshRate.Denominator = 1; - _swapDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - _swapDescription.SampleDesc.Count = 1; - _swapDescription.SampleDesc.Quality = 0; - _swapDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - _swapDescription.BufferCount = 2; - _swapDescription.OutputWindow = gameWindow.WindowHandle(); - _swapDescription.Windowed = gameWindow.Mode() != GameWindowMode::Fullscreen; - _swapDescription.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; - _swapDescription.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; return true; } - bool SwapChain::Apply() { - auto adapter = _device->Adapter(); - auto dxAdapter = adapter->_adapter; + bool SwapChain::Initialize(GraphicsDevice& device, GameWindow const& gameWindow) { + const auto bounds = gameWindow.ClientBounds(); - IDXGIFactory* dxFactory = nullptr; - if FAILED(dxAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&dxFactory)) - return false; + _description.Width = static_cast(bounds.Width); + _description.Height = static_cast(bounds.Height); + _description.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + _description.SampleDesc.Count = 1; + _description.SampleDesc.Quality = 0; + _description.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + _description.BufferCount = 2; + _description.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + _description.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + _description.AlphaMode = DXGI_ALPHA_MODE::DXGI_ALPHA_MODE_UNSPECIFIED; + _fullScreenDescription.RefreshRate.Numerator = 60; + _fullScreenDescription.RefreshRate.Denominator = 1; + _fullScreenDescription.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + _fullScreenDescription.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + _fullScreenDescription.Windowed = gameWindow.Mode() != GameWindowMode::Fullscreen; - auto dxdevice = _device->_device; + return internalInit(device, gameWindow, _swapChain, _description, _fullScreenDescription); + } - if FAILED(dxFactory->CreateSwapChain(dxdevice, &_swapDescription, &_swapChain)) - { - dxFactory->Release(); - dxFactory = nullptr; - return false; - } - - dxFactory->Release(); - dxFactory = nullptr; - - return true; - } + bool SwapChain::Initialize(GraphicsDevice& device, GameWindow const& gameWindow, DXGI_SWAP_CHAIN_DESC1 const& desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC const& fullScreenDesc) + { + return internalInit(device, gameWindow, _swapChain, _description, _fullScreenDescription); + } } \ No newline at end of file diff --git a/framework/platform/swapchain-dx.hpp b/framework/platform/swapchain-dx.hpp index f74bc76..e033c8b 100644 --- a/framework/platform/swapchain-dx.hpp +++ b/framework/platform/swapchain-dx.hpp @@ -3,14 +3,11 @@ #include "../graphics/swapchain.hpp" #include "window-dx.hpp" -#include "dxgi.h" -#include "d3d11.h" +#include "dxheaders.hpp" namespace xna { class SwapChain : public ISwapChain{ public: - SwapChain(GraphicsDevice* device); - virtual ~SwapChain() override { if (_swapChain) { _swapChain->Release(); @@ -18,8 +15,8 @@ namespace xna { } } - virtual bool Initialize(GameWindow const& gameWindow) override; - virtual bool Apply() override; + virtual bool Initialize(GraphicsDevice& device, GameWindow const& gameWindow) override; + bool Initialize(GraphicsDevice& device, GameWindow const& gameWindow, DXGI_SWAP_CHAIN_DESC1 const& desc, DXGI_SWAP_CHAIN_FULLSCREEN_DESC const& fullScreenDesc); bool GetBackBuffer(ID3D11Texture2D*& texture2D) { if FAILED(_swapChain->GetBuffer(0, __uuidof(texture2D), (void**)(&texture2D))) @@ -29,9 +26,9 @@ namespace xna { } public: - IDXGISwapChain* _swapChain{ nullptr }; - DXGI_SWAP_CHAIN_DESC _swapDescription{}; - GraphicsDevice* _device{ nullptr }; + IDXGISwapChain1* _swapChain{ nullptr }; + DXGI_SWAP_CHAIN_DESC1 _description{}; + DXGI_SWAP_CHAIN_FULLSCREEN_DESC _fullScreenDescription{}; }; } diff --git a/framework/xna.cpp b/framework/xna.cpp index 9853fc6..1cccff0 100644 --- a/framework/xna.cpp +++ b/framework/xna.cpp @@ -21,7 +21,6 @@ public: void Initialize() override { graphics->Initialize(); - const auto modes= _graphicsDevice->Adapter()->SupportedDisplayModes(); Game::Initialize(); }