From 5fffba8e594081e2eb6b27e80270a27837617982 Mon Sep 17 00:00:00 2001 From: Danilo Date: Fri, 2 Aug 2024 16:40:06 -0300 Subject: [PATCH] =?UTF-8?q?Implementa=C3=A7=C3=B5es=20em=20GraphicsDevice?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- framework/platform-dx/blendstate.cpp | 2 +- framework/platform-dx/depthstencilstate.cpp | 2 +- framework/platform-dx/device.cpp | 412 +++++++++----------- framework/platform-dx/gdevicemanager.cpp | 15 +- framework/platform-dx/swapchain.cpp | 2 +- inc/xna/default.hpp | 8 + inc/xna/graphics/device.hpp | 71 ++-- inc/xna/xna-dx.hpp | 25 +- 8 files changed, 234 insertions(+), 303 deletions(-) diff --git a/framework/platform-dx/blendstate.cpp b/framework/platform-dx/blendstate.cpp index 74ffe21..6ee8ebe 100644 --- a/framework/platform-dx/blendstate.cpp +++ b/framework/platform-dx/blendstate.cpp @@ -122,7 +122,7 @@ namespace xna { } if (!impl->dxBlendState) { - Exception::Throw(Exception::INVALID_OPERATION); + Initialize(); } m_device->impl->_context->OMSetBlendState( diff --git a/framework/platform-dx/depthstencilstate.cpp b/framework/platform-dx/depthstencilstate.cpp index 0ee93db..dcbf545 100644 --- a/framework/platform-dx/depthstencilstate.cpp +++ b/framework/platform-dx/depthstencilstate.cpp @@ -63,7 +63,7 @@ namespace xna { } if (!impl->dxDepthStencil) { - Exception::Throw(Exception::INVALID_OPERATION); + Initialize(); } m_device->impl->_context->OMSetDepthStencilState(impl->dxDepthStencil.Get(), 0); diff --git a/framework/platform-dx/device.cpp b/framework/platform-dx/device.cpp index 1f625b8..1e297d8 100644 --- a/framework/platform-dx/device.cpp +++ b/framework/platform-dx/device.cpp @@ -1,8 +1,167 @@ #include "xna/xna-dx.hpp" -#include "xna/game/gdevicemanager.hpp" namespace xna { - static void reset(GraphicsDevice::PlatformImplementation& impl) + static void reset(GraphicsDevice::PlatformImplementation& impl); + static void createDevice(GraphicsDevice::PlatformImplementation& impl, GraphicsAdapter& currentAdapter); + static void initAndApplyState(P_BlendState& blendState, P_RasterizerState& rasterizerState, + P_DepthStencilState& depthStencilState, P_SamplerStateCollection& samplerStates, P_GraphicsDevice const& device); + + GraphicsDevice::GraphicsDevice() { + impl = unew(); + adapter = GraphicsAdapter::DefaultAdapter(); + } + + GraphicsDevice::GraphicsDevice(sptr const& adapter, GraphicsProfile const& graphicsProfile, sptr const& presentationParameters) + : adapter(adapter), graphicsProfile(graphicsProfile), presentationParameters(presentationParameters) { + impl = unew(); + + blendState = xna::BlendState::Opaque(); + depthStencilState = xna::DepthStencilState::Default(); + rasterizerState = xna::RasterizerState::CullCounterClockwise(); + samplerStateCollection = snew(); + } + + void GraphicsDevice::Initialize() { + auto _this = shared_from_this(); + + reset(*impl); + createDevice(*impl, *adapter); + + auto hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&impl->_factory); + + if FAILED(hr) + Exception::Throw(Exception::FAILED_TO_CREATE); + + viewport = xna::Viewport(0.0F, 0.0F, + presentationParameters->BackBufferWidth, + presentationParameters->BackBufferHeight, + 0.0F, 1.F); + + const auto backColor = Colors::CornflowerBlue; + const auto backColorV3 = backColor.ToVector3(); + + impl->_backgroundColor[0] = backColorV3.X; + impl->_backgroundColor[1] = backColorV3.Y; + impl->_backgroundColor[2] = backColorV3.Z; + impl->_backgroundColor[3] = 1.0f; + + impl->_swapChain = snew(_this); + impl->_swapChain->Initialize(); + + auto hwnd = reinterpret_cast(presentationParameters->DeviceWindowHandle); + hr = impl->_factory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER); + + if (FAILED(hr)) + Exception::Throw(Exception::FAILED_TO_MAKE_WINDOW_ASSOCIATION); + + impl->_renderTarget2D = snew(_this); + impl->_renderTarget2D->Initialize(); + impl->_renderTarget2D->Apply(); + + D3D11_VIEWPORT view = DxHelpers::ViewportToDx(viewport); + impl->_context->RSSetViewports(1, &view); + + initAndApplyState(blendState, rasterizerState, depthStencilState, samplerStateCollection, _this); + + const auto currentPresenInterval = presentationParameters->PresentationInterval; + + switch (currentPresenInterval) + { + case PresentInterval::Default: + case PresentInterval::One: + case PresentInterval::Two: + impl->vSyncValue = 1; + break; + case PresentInterval::Immediate: + impl->vSyncValue = 0; + break; + default: + impl->vSyncValue = 1; + break; + } + } + + bool GraphicsDevice::Present() const { + const auto currentPresenInterval = presentationParameters->PresentationInterval; + bool result = impl->_swapChain->Present(impl->vSyncValue != 0); + + impl->_context->OMSetRenderTargets( + 1, + impl->_renderTarget2D->render_impl->_renderTargetView.GetAddressOf(), + nullptr); + + return result; + } + + void GraphicsDevice::Clear(Color const& color) const { + if (!impl) return; + + const auto v4 = color.ToVector4(); + + impl->_backgroundColor[0] = v4.X; + impl->_backgroundColor[1] = v4.Y; + impl->_backgroundColor[2] = v4.Z; + impl->_backgroundColor[3] = v4.W; + + impl->_context->ClearRenderTargetView( + impl->_renderTarget2D->render_impl->_renderTargetView.Get(), + impl->_backgroundColor); + } + + void GraphicsDevice::Clear(ClearOptions options, Color const& color, float depth, Int stencil) const { + if (!impl) return; + + switch (options) + { + case xna::ClearOptions::DepthBuffer: + Exception::Throw(Exception::NOT_IMPLEMENTED); + break; + case xna::ClearOptions::Stencil: + Exception::Throw(Exception::NOT_IMPLEMENTED); + break; + case xna::ClearOptions::Target: + Clear(color); + break; + default: + return; + } + } + + void GraphicsDevice::Viewport(xna::Viewport const& value) { + viewport = value; + const auto view = DxHelpers::ViewportToDx(viewport); + + impl->_context->RSSetViewports(1, &view); + } + + void GraphicsDevice::BlendState(sptr const& value) { + blendState = value; + blendState->Apply(); + } + + void GraphicsDevice::DepthStencilState(sptr const& value) { + depthStencilState = value; + depthStencilState->Apply(); + } + + void GraphicsDevice::RasterizerState(sptr const& value) { + rasterizerState = value; + rasterizerState->Apply(); + } + + void GraphicsDevice::Reset(sptr const& parameters, sptr const& graphicsAdapter){ + impl = unew(); + adapter = graphicsAdapter; + presentationParameters = parameters; + + Initialize(); + } + + // + // INTERNAL + // + + void reset(GraphicsDevice::PlatformImplementation& impl) { if (impl._device) { impl._device->Release(); @@ -20,7 +179,7 @@ namespace xna { } } - static void createDevice(GraphicsDevice::PlatformImplementation& impl) { + void createDevice(GraphicsDevice::PlatformImplementation& impl, GraphicsAdapter& currentAdapter) { // // See ref // @@ -34,11 +193,10 @@ namespace xna { auto createDeviceFlags = 0; #if _DEBUG createDeviceFlags = D3D11_CREATE_DEVICE_FLAG::D3D11_CREATE_DEVICE_DEBUG; -#endif +#endif + + const auto& pAdapter = GraphicsAdapter::UseNullDevice() ? NULL : currentAdapter.impl->dxAdapter.Get(); - const auto& currentAdapter = impl._adapter; - const auto& pAdapter = GraphicsAdapter::UseNullDevice() ? NULL : currentAdapter->impl->dxAdapter.Get(); - // // if pAdapter is not NULL driverType must be D3D_DRIVER_TYPE_UNKNOWN // @@ -75,237 +233,19 @@ namespace xna { Exception::Throw(Exception::FAILED_TO_CREATE); } - static void initAndApplyState(GraphicsDevice::PlatformImplementation& impl, PGraphicsDevice const& device) { - impl._blendState->Bind(device); - impl._blendState->Initialize(); - impl._blendState->Apply(); + static void initAndApplyState(P_BlendState& blendState, P_RasterizerState& rasterizerState, P_DepthStencilState& depthStencilState, P_SamplerStateCollection& samplerStates, P_GraphicsDevice const& device) { + blendState->Bind(device); + blendState->Initialize(); + blendState->Apply(); - impl._rasterizerState->Bind(device); - impl._rasterizerState->Initialize(); - impl._rasterizerState->Apply(); + rasterizerState->Bind(device); + rasterizerState->Initialize(); + rasterizerState->Apply(); - impl._depthStencilState->Bind(device); - impl._depthStencilState->Initialize(); - impl._depthStencilState->Apply(); + depthStencilState->Bind(device); + depthStencilState->Initialize(); + depthStencilState->Apply(); - impl._samplerStates->Apply(*device); - } - - GraphicsDevice::GraphicsDevice() { - impl = unew(); - impl->_adapter = GraphicsAdapter::DefaultAdapter(); - } - - GraphicsDevice::GraphicsDevice(GraphicsDeviceInformation const& info) { - impl = unew(); - - impl->_adapter = info.Adapter; - impl->_presentationParameters = info.PresentParameters; - } - - GraphicsDevice::GraphicsDevice(sptr const& adapter, GraphicsProfile const& graphicsProfile, sptr const& presentationParameters) { - impl = unew(); - impl->_adapter = adapter; - impl->_presentationParameters = presentationParameters; - } - - bool GraphicsDevice::Initialize() { - auto _this = shared_from_this(); - - if (!impl) - impl = uptr(); - - reset(*impl); - - createDevice(*impl); - - auto hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&impl->_factory); - - if FAILED(hr) - Exception::Throw(Exception::FAILED_TO_CREATE); - - //const auto bounds = impl->_gameWindow->ClientBounds(); - - impl->_viewport = xna::Viewport(0.0F, 0.0F, - impl->_presentationParameters->BackBufferWidth, - impl->_presentationParameters->BackBufferHeight, - 0.0F, 1.F); - - //COLORREF color = impl->_gameWindow->impl->Color(); - const auto backColor = Colors::CornflowerBlue; - const auto backColorV3 = backColor.ToVector3(); - - impl->_backgroundColor[0] = backColorV3.X; - impl->_backgroundColor[1] = backColorV3.Y; - impl->_backgroundColor[2] = backColorV3.Z; - impl->_backgroundColor[3] = 1.0f; - - impl->_swapChain = snew(_this); - impl->_swapChain->Initialize(); - - auto hwnd = reinterpret_cast(impl->_presentationParameters->DeviceWindowHandle); - hr = impl->_factory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER); - - if (FAILED(hr)) - Exception::Throw(Exception::FAILED_TO_MAKE_WINDOW_ASSOCIATION); - - impl->_renderTarget2D = snew(_this); - - if (!impl->_renderTarget2D->Initialize()) - return false; - - impl->_renderTarget2D->Apply(); - - D3D11_VIEWPORT view{}; - view.TopLeftX = impl->_viewport.X; - view.TopLeftY = impl->_viewport.Y; - view.Width = impl->_viewport.Width; - view.Height = impl->_viewport.Height; - view.MinDepth = impl->_viewport.MinDetph; - view.MaxDepth = impl->_viewport.MaxDepth; - - impl->_context->RSSetViewports(1, &view); - - initAndApplyState(*impl, _this); - - const auto currentPresenInterval = impl->_presentationParameters->PresentationInterval; - - switch (currentPresenInterval) - { - case PresentInterval::Default: - case PresentInterval::One: - case PresentInterval::Two: - impl->vSyncValue = 1; - break; - case PresentInterval::Immediate: - impl->vSyncValue = 0; - break; - default: - impl->vSyncValue = 1; - break; - } - - return true; - } - - bool GraphicsDevice::Present() const { - const auto currentPresenInterval = impl->_presentationParameters->PresentationInterval; - bool result = impl->_swapChain->Present(impl->vSyncValue != 0); - - impl->_context->OMSetRenderTargets( - 1, - impl->_renderTarget2D->render_impl->_renderTargetView.GetAddressOf(), - nullptr); - - return result; - } - - void GraphicsDevice::Clear(Color const& color) const { - if (!impl) return; - - const auto v4 = color.ToVector4(); - - impl->_backgroundColor[0] = v4.X; - impl->_backgroundColor[1] = v4.Y; - impl->_backgroundColor[2] = v4.Z; - impl->_backgroundColor[3] = v4.W; - - impl->_context->ClearRenderTargetView( - impl->_renderTarget2D->render_impl->_renderTargetView.Get(), - impl->_backgroundColor); - } - - void GraphicsDevice::Clear(ClearOptions options, Color const& color, float depth, Int stencil) { - if (!impl) return; - - switch (options) - { - case xna::ClearOptions::DepthBuffer: - Exception::Throw(Exception::NOT_IMPLEMENTED); - break; - case xna::ClearOptions::Stencil: - Exception::Throw(Exception::NOT_IMPLEMENTED); - break; - case xna::ClearOptions::Target: - Clear(color); - break; - default: - return; - } - } - - void GraphicsDevice::Clear(ClearOptions options, Vector4 const& color, float depth, Int stencil) { - if (!impl) return; - - - } - - sptr GraphicsDevice::Adapter() const { - if (!impl) return nullptr; - - return impl->_adapter; - } - - xna::Viewport GraphicsDevice::Viewport() const { - if (!impl) return {}; - - return impl->_viewport; - } - - void GraphicsDevice::Viewport(xna::Viewport const& viewport) { - if (!impl) return; - - impl->_viewport = viewport; - } - - void GraphicsDevice::UseVSync(bool value) { - if (!impl) return; - - impl->vSyncValue = static_cast(value); - } - - - sptr GraphicsDevice::BlendState() const { - return impl->_blendState; - } - - void GraphicsDevice::BlendState(sptr const& value) { - impl->_blendState = value; - } - - sptr GraphicsDevice::DepthStencilState() const { - return impl->_depthStencilState; - } - - void GraphicsDevice::DepthStencilState(sptr const& value) { - impl->_depthStencilState = value; - } - - sptr GraphicsDevice::RasterizerState() const { - return impl->_rasterizerState; - } - - void GraphicsDevice::RasterizerState(sptr const& value) { - impl->_rasterizerState = value; - } - - sptr GraphicsDevice::SamplerStates() const { - return impl->_samplerStates; - } - - Int GraphicsDevice::MultiSampleMask() const { - return impl->_multiSampleMask; - } - - void GraphicsDevice::MultiSampleMask(Int value) { - impl->_multiSampleMask = value; - } - - void GraphicsDevice::Reset(sptr const& presentationParameters, sptr const& graphicsAdapter){ - impl = unew(); - impl->_adapter = graphicsAdapter; - impl->_presentationParameters = presentationParameters; - - Initialize(); + samplerStates->Apply(*device); } } \ No newline at end of file diff --git a/framework/platform-dx/gdevicemanager.cpp b/framework/platform-dx/gdevicemanager.cpp index df38105..bfdacdf 100644 --- a/framework/platform-dx/gdevicemanager.cpp +++ b/framework/platform-dx/gdevicemanager.cpp @@ -74,19 +74,18 @@ namespace xna { } if (flag2) - CreateDevice(*bestDevice); - - auto presentationParameters = device->PresentParameters(); + CreateDevice(*bestDevice); screenDeviceName = device->Adapter()->DeviceName(); + const auto presentationParameters = device->PresentParameters(); - isReallyFullScreen = presentationParameters.IsFullscreen; + isReallyFullScreen = presentationParameters->IsFullscreen; - if (presentationParameters.BackBufferWidth != 0) - clientWidth = presentationParameters.BackBufferWidth; + if (presentationParameters->BackBufferWidth != 0) + clientWidth = presentationParameters->BackBufferWidth; - if (presentationParameters.BackBufferHeight != 0) - clientHeight = presentationParameters.BackBufferHeight; + if (presentationParameters->BackBufferHeight != 0) + clientHeight = presentationParameters->BackBufferHeight; isDeviceDirty = false; diff --git a/framework/platform-dx/swapchain.cpp b/framework/platform-dx/swapchain.cpp index dc76cd9..04e6ebe 100644 --- a/framework/platform-dx/swapchain.cpp +++ b/framework/platform-dx/swapchain.cpp @@ -48,7 +48,7 @@ namespace xna { Exception::Throw(Exception::UNABLE_TO_INITIALIZE); } - const auto parameters = m_device->impl->_presentationParameters; + const auto parameters = m_device->PresentParameters(); impl->dxDescription.Width = static_cast(parameters->BackBufferWidth); impl->dxDescription.Height = static_cast(parameters->BackBufferHeight); diff --git a/inc/xna/default.hpp b/inc/xna/default.hpp index ad0327a..4725e7a 100644 --- a/inc/xna/default.hpp +++ b/inc/xna/default.hpp @@ -194,6 +194,14 @@ namespace xna { struct GamePadState; struct KeyboardState; struct MouseState; + + using P_BlendState = sptr; + using P_DepthStencilState = sptr; + using P_GraphicsAdapter = sptr; + using P_GraphicsDevice = sptr; + using P_RasterizerState = sptr; + using P_PresentationParameters = sptr; + using P_SamplerStateCollection = sptr; } diff --git a/inc/xna/graphics/device.hpp b/inc/xna/graphics/device.hpp index 46c6a31..08f259e 100644 --- a/inc/xna/graphics/device.hpp +++ b/inc/xna/graphics/device.hpp @@ -3,59 +3,60 @@ #include "../default.hpp" #include "presentparams.hpp" +#include "viewport.hpp" namespace xna { //Performs primitive-based rendering, creates resources, handles system-level variables, adjusts gamma ramp levels, and creates shaders. class GraphicsDevice : public std::enable_shared_from_this { public: GraphicsDevice(); - GraphicsDevice(GraphicsDeviceInformation const& info); - GraphicsDevice(sptr const& adapter, GraphicsProfile const& graphicsProfile, sptr const& presentationParameters); + + GraphicsDevice(P_GraphicsAdapter const& adapter, GraphicsProfile const& graphicsProfile, P_PresentationParameters const& presentationParameters); //Gets the graphics adapter. - sptr Adapter() const; - + inline P_GraphicsAdapter Adapter() const { return adapter; } //Gets or sets a system-defined instance of a blend state object initialized for alpha blending. The default value is BlendState.Opaque. - sptr BlendState() const; + inline P_BlendState BlendState() const { return blendState; } //Gets or sets a system-defined instance of a blend state object initialized for alpha blending. The default value is BlendState.Opaque. - void BlendState(sptr const& value); + void BlendState(P_BlendState const& value); //Gets or sets a system-defined instance of a depth-stencil state object. The default value is DepthStencilState.Default. - sptr DepthStencilState() const; + inline P_DepthStencilState DepthStencilState() const { return depthStencilState; } //Gets or sets a system-defined instance of a depth-stencil state object. The default value is DepthStencilState.Default. - void DepthStencilState(sptr const& value); + void DepthStencilState(P_DepthStencilState const& value); //Gets or sets rasterizer state. The default value is RasterizerState.CullCounterClockwise. - sptr RasterizerState() const; + inline P_RasterizerState RasterizerState() const { return rasterizerState; } //Gets or sets rasterizer state. The default value is RasterizerState.CullCounterClockwise. - void RasterizerState(sptr const& value); + void RasterizerState(P_RasterizerState const& value); //Retrieves a collection of SamplerState objects for the current GraphicsDevice. - sptr SamplerStates() const; - - //Gets or sets a bitmask controlling modification of the samples in a multisample render target. The default value is -1 (0xffffffff). - Int MultiSampleMask() const; - //Gets or sets a bitmask controlling modification of the samples in a multisample render target. The default value is -1 (0xffffffff). - void MultiSampleMask(Int value); - - constexpr GraphicsProfile Profile() const { - return GraphicsProfile::HiDef; - } - - constexpr PresentationParameters PresentParameters() const { - return PresentationParameters(); - } - + inline P_SamplerStateCollection SamplerStates() const { return samplerStateCollection; } + //Gets the graphics profile. + constexpr GraphicsProfile Profile() const { return graphicsProfile; } + //Gets the presentation parameters associated with this graphics device. + P_PresentationParameters PresentParameters() const { return presentationParameters; } + //Clears resource buffers. void Clear(Color const& color) const; - void Clear(ClearOptions options, Color const& color, float depth, Int stencil); - void Clear(ClearOptions options, Vector4 const& color, float depth, Int stencil); - bool Initialize(); - bool Present() const; - - void Reset(sptr const& presentationParameters, sptr const& graphicsAdapter); - - xna::Viewport Viewport() const; + //Clears resource buffers. + void Clear(ClearOptions options, Color const& color, float depth, Int stencil) const; + //Presents the display with the contents of the next buffer in the sequence of back buffers owned by the GraphicsDevice. + bool Present() const; + //Resets the presentation parameters for the current GraphicsDevice. + void Reset(P_PresentationParameters const& presentationParameters, P_GraphicsAdapter const& graphicsAdapter); + //Gets or sets a viewport identifying the portion of the render target to receive draw calls. + constexpr xna::Viewport Viewport() const { return viewport; } + //Gets or sets a viewport identifying the portion of the render target to receive draw calls. void Viewport(xna::Viewport const& viewport); - void UseVSync(bool use); + + void Initialize(); - //void DrawPrimitives(PrimitiveType primitiveType, Int startVertex, Int primitiveCount); + private: + P_GraphicsAdapter adapter{ nullptr }; + P_BlendState blendState{ nullptr }; + P_DepthStencilState depthStencilState{ nullptr }; + P_RasterizerState rasterizerState{ nullptr }; + P_SamplerStateCollection samplerStateCollection{ nullptr }; + P_PresentationParameters presentationParameters{ nullptr }; + GraphicsProfile graphicsProfile{ GraphicsProfile::HiDef }; + xna::Viewport viewport{}; public: struct PlatformImplementation; diff --git a/inc/xna/xna-dx.hpp b/inc/xna/xna-dx.hpp index 15d64af..0493488 100644 --- a/inc/xna/xna-dx.hpp +++ b/inc/xna/xna-dx.hpp @@ -831,31 +831,14 @@ namespace xna { uptr _dxAudioEngine = nullptr; }; - struct GraphicsDevice::PlatformImplementation { - PlatformImplementation() { - _blendState = xna::BlendState::Opaque(); - _depthStencilState = xna::DepthStencilState::Default(); - _rasterizerState = xna::RasterizerState::CullCounterClockwise(); - _samplerStates = snew(); - } - - public: + struct GraphicsDevice::PlatformImplementation { comptr _device = nullptr; comptr _context = nullptr; - comptr _factory = nullptr; - - PBlendState _blendState = nullptr; - PRasterizerState _rasterizerState = nullptr; - PDepthStencilState _depthStencilState = nullptr; - PSamplerStateCollection _samplerStates = nullptr; - Int _multiSampleMask = 0xffffffff; - + comptr _factory = nullptr; + sptr _swapChain = nullptr; - sptr _adapter = nullptr; sptr _renderTarget2D = nullptr; - intptr_t windowHandle{ 0 }; - xna::Viewport _viewport{}; - sptr _presentationParameters; + intptr_t windowHandle{ 0 }; D3D_FEATURE_LEVEL featureLevels[7] = {