diff --git a/includes/xna-dx/implementations.hpp b/includes/xna-dx/implementations.hpp index c1dfdfc..7c0f302 100644 --- a/includes/xna-dx/implementations.hpp +++ b/includes/xna-dx/implementations.hpp @@ -44,6 +44,9 @@ namespace xna { D3D_FEATURE_LEVEL CurrentFeatureLevel{ D3D_FEATURE_LEVEL_11_1 }; + void Create(GraphicsAdapter& currentAdapter); + void Reset(); + private: friend class GraphicsDevice; float backgroundColor[4] = { 0, 0, 0, 0 }; diff --git a/sources/framework-dx/CMakeLists.txt b/sources/framework-dx/CMakeLists.txt index 56bd965..04bb679 100644 --- a/sources/framework-dx/CMakeLists.txt +++ b/sources/framework-dx/CMakeLists.txt @@ -24,7 +24,7 @@ add_library (Xn65DX STATIC "init.cpp" "audioengine.cpp" "effect.cpp" -"screen.cpp") +"screen.cpp" ) if (CMAKE_VERSION VERSION_GREATER 3.12) set_property(TARGET Xn65DX PROPERTY CXX_STANDARD 20) diff --git a/sources/framework-dx/device.cpp b/sources/framework-dx/device.cpp index d8fadb2..9c344ca 100644 --- a/sources/framework-dx/device.cpp +++ b/sources/framework-dx/device.cpp @@ -1,222 +1,11 @@ #include "xna-dx/framework.hpp" namespace xna { - static void reset(GraphicsDeviceImplementation& impl); - static void createDevice(GraphicsDeviceImplementation& impl, GraphicsAdapter& currentAdapter); - static void initAndApplyState(P_BlendState& blendState, P_RasterizerState& rasterizerState, - P_DepthStencilState& depthStencilState, P_SamplerStateCollection& samplerStates, P_GraphicsDevice const& device); - - GraphicsDevice::GraphicsDevice() { - Implementation = unew(); - adapter = GraphicsAdapter::DefaultAdapter(); - } - - GraphicsDevice::GraphicsDevice(sptr const& adapter, GraphicsProfile const& graphicsProfile, sptr const& presentationParameters) - : adapter(adapter), graphicsProfile(graphicsProfile), presentationParameters(presentationParameters) { - Implementation = unew(); - - blendState = xna::BlendState::Opaque(); - depthStencilState = xna::DepthStencilState::Default(); - rasterizerState = xna::RasterizerState::CullCounterClockwise(); - samplerStateCollection = snew(); - } - - void GraphicsDevice::Initialize() { - reset(*Implementation); - - auto _this = shared_from_this(); - - createDevice(*Implementation, *adapter); - - // - // Background - // - - const auto backColor = Colors::CornflowerBlue; - const auto backColorV3 = backColor.ToVector3(); - - Implementation->backgroundColor[0] = backColorV3.X; - Implementation->backgroundColor[1] = backColorV3.Y; - Implementation->backgroundColor[2] = backColorV3.Z; - Implementation->backgroundColor[3] = 1.0f; - - // - // Window Association - // - - auto hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&Implementation->Factory); - - if FAILED(hr) - Exception::Throw(Exception::FAILED_TO_CREATE); - - auto hwnd = reinterpret_cast(presentationParameters->DeviceWindowHandle); - hr = Implementation->Factory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER); - - if (FAILED(hr)) - Exception::Throw(Exception::FAILED_TO_MAKE_WINDOW_ASSOCIATION); - - // - // Viewport - // - - viewport = xna::Viewport(0.0F, 0.0F, - presentationParameters->BackBufferWidth, - presentationParameters->BackBufferHeight, - 0.0F, 1.F); - - D3D11_VIEWPORT view = DxHelpers::ViewportToDx(viewport); - Implementation->Context->RSSetViewports(1, &view); - - // - // States - // - - initAndApplyState(blendState, rasterizerState, depthStencilState, samplerStateCollection, _this); - - // - // Presentation - // - - const auto currentPresenInterval = presentationParameters->PresentationInterval; - - switch (currentPresenInterval) - { - case PresentInterval::Default: - case PresentInterval::One: - case PresentInterval::Two: - Implementation->vSyncValue = 1; - break; - case PresentInterval::Immediate: - Implementation->vSyncValue = 0; - break; - default: - Implementation->vSyncValue = 1; - break; - } - - Implementation->SwapChain = snew(_this); - Implementation->SwapChain->Initialize(); - - // - //Render Target - // - - if (renderTarget) { - renderTarget->Initialize(); - Implementation->RenderTarget2D = renderTarget; - } - else { - Implementation->RenderTarget2D = RenderTarget2D::FromBackBuffer(_this); - } - - const auto& renderView = Implementation->RenderTarget2D->impl2->_renderTargetView; - Implementation->Context->OMSetRenderTargets(1, renderView.GetAddressOf(), nullptr); - } - - bool GraphicsDevice::Present() const { - bool result = Implementation->SwapChain->Present(Implementation->vSyncValue != 0); - - Implementation->Context->OMSetRenderTargets( - 1, - Implementation->RenderTarget2D->impl2->_renderTargetView.GetAddressOf(), - nullptr); - - return result; - } - - void GraphicsDevice::Clear(Color const& color) const { - if (!Implementation) return; - - const auto v4 = color.ToVector4(); - - Implementation->backgroundColor[0] = v4.X; - Implementation->backgroundColor[1] = v4.Y; - Implementation->backgroundColor[2] = v4.Z; - Implementation->backgroundColor[3] = v4.W; - - Implementation->Context->ClearRenderTargetView( - Implementation->RenderTarget2D->impl2->_renderTargetView.Get(), - Implementation->backgroundColor); - } - - void GraphicsDevice::Clear(ClearOptions options, Color const& color, float depth, Int stencil) const { - if (!Implementation) 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); - - Implementation->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){ - Implementation = unew(); - adapter = graphicsAdapter; - presentationParameters = parameters; - - Initialize(); - } - - // - // INTERNAL - // - - void reset(GraphicsDeviceImplementation& impl) - { - if (impl.Device) { - impl.Device->Release(); - impl.Device = nullptr; - } - - if (impl.Context) { - impl.Context->Release(); - impl.Context = nullptr; - } - - if (impl.Factory) { - impl.Factory->Release(); - impl.Factory = nullptr; - } - } - - void createDevice(GraphicsDeviceImplementation& impl, GraphicsAdapter& currentAdapter) { - // + void GraphicsDeviceImplementation::Create(GraphicsAdapter& currentAdapter) { // See ref // // D3D_DRIVER_TYPE // https://learn.microsoft.com/en-us/windows/win32/api/d3dcommon/ne-d3dcommon-d3d_driver_type - // // D3D11CreateDevice function // https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-d3d11createdevice // @@ -248,22 +37,228 @@ namespace xna { //UINT Flags, createDeviceFlags, //_In_reads_opt_( FeatureLevels ) CONST D3D_FEATURE_LEVEL* pFeatureLevels, - GraphicsDeviceImplementation::FeatureLevels, + FeatureLevels, //UINT FeatureLevels, 7, //UINT SDKVersion, D3D11_SDK_VERSION, //_COM_Outptr_opt_ ID3D11Device** ppDevice - impl.Device.GetAddressOf(), + Device.GetAddressOf(), //_Out_opt_ D3D_FEATURE_LEVEL* pFeatureLevel, - &impl.CurrentFeatureLevel, + &CurrentFeatureLevel, //_COM_Outptr_opt_ ID3D11DeviceContext** ppImmediateContext - impl.Context.GetAddressOf()); + Context.GetAddressOf()); if FAILED(hr) Exception::Throw(Exception::FAILED_TO_CREATE); } + void GraphicsDeviceImplementation::Reset() { + if (Device) { + Device->Release(); + Device = nullptr; + } + + if (Context) { + Context->Release(); + Context = nullptr; + } + + if (Factory) { + Factory->Release(); + Factory = nullptr; + } + } + + static void initAndApplyState(P_BlendState& blendState, P_RasterizerState& rasterizerState, + P_DepthStencilState& depthStencilState, P_SamplerStateCollection& samplerStates, P_GraphicsDevice const& device); + + GraphicsDevice::GraphicsDevice() { + Implementation = unew(); + adapter = GraphicsAdapter::DefaultAdapter(); + } + + GraphicsDevice::GraphicsDevice(sptr const& adapter, GraphicsProfile const& graphicsProfile, sptr const& presentationParameters) + : adapter(adapter), graphicsProfile(graphicsProfile), presentationParameters(presentationParameters) { + Implementation = unew(); + + blendState = xna::BlendState::Opaque(); + depthStencilState = xna::DepthStencilState::Default(); + rasterizerState = xna::RasterizerState::CullCounterClockwise(); + samplerStateCollection = snew(); + } + + void GraphicsDevice::Initialize() { + Implementation->Reset(); + + auto _this = shared_from_this(); + + Implementation->Create(*adapter); + + // + // Background + // + + const auto backColor = Colors::CornflowerBlue; + const auto backColorV3 = backColor.ToVector3(); + + Implementation->backgroundColor[0] = backColorV3.X; + Implementation->backgroundColor[1] = backColorV3.Y; + Implementation->backgroundColor[2] = backColorV3.Z; + Implementation->backgroundColor[3] = 1.0f; + + // + // Window Association + // + + auto hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&Implementation->Factory); + + if FAILED(hr) + Exception::Throw(Exception::FAILED_TO_CREATE); + + auto hwnd = reinterpret_cast(presentationParameters->DeviceWindowHandle); + hr = Implementation->Factory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER); + + if (FAILED(hr)) + Exception::Throw(Exception::FAILED_TO_MAKE_WINDOW_ASSOCIATION); + + // + // Viewport + // + + viewport = xna::Viewport(0.0F, 0.0F, + presentationParameters->BackBufferWidth, + presentationParameters->BackBufferHeight, + 0.0F, 1.F); + + D3D11_VIEWPORT view = DxHelpers::ViewportToDx(viewport); + Implementation->Context->RSSetViewports(1, &view); + + // + // States + // + + initAndApplyState(blendState, rasterizerState, depthStencilState, samplerStateCollection, _this); + + // + // Presentation + // + + const auto currentPresenInterval = presentationParameters->PresentationInterval; + + switch (currentPresenInterval) + { + case PresentInterval::Default: + case PresentInterval::One: + case PresentInterval::Two: + Implementation->vSyncValue = 1; + break; + case PresentInterval::Immediate: + Implementation->vSyncValue = 0; + break; + default: + Implementation->vSyncValue = 1; + break; + } + + Implementation->SwapChain = snew(_this); + Implementation->SwapChain->Initialize(); + + // + //Render Target + // + + if (renderTarget) { + renderTarget->Initialize(); + Implementation->RenderTarget2D = renderTarget; + } + else { + Implementation->RenderTarget2D = RenderTarget2D::FromBackBuffer(_this); + } + + const auto& renderView = Implementation->RenderTarget2D->impl2->_renderTargetView; + Implementation->Context->OMSetRenderTargets(1, renderView.GetAddressOf(), nullptr); + } + + bool GraphicsDevice::Present() const { + bool result = Implementation->SwapChain->Present(Implementation->vSyncValue != 0); + + Implementation->Context->OMSetRenderTargets( + 1, + Implementation->RenderTarget2D->impl2->_renderTargetView.GetAddressOf(), + nullptr); + + return result; + } + + void GraphicsDevice::Clear(Color const& color) const { + if (!Implementation) return; + + const auto v4 = color.ToVector4(); + + Implementation->backgroundColor[0] = v4.X; + Implementation->backgroundColor[1] = v4.Y; + Implementation->backgroundColor[2] = v4.Z; + Implementation->backgroundColor[3] = v4.W; + + Implementation->Context->ClearRenderTargetView( + Implementation->RenderTarget2D->impl2->_renderTargetView.Get(), + Implementation->backgroundColor); + } + + void GraphicsDevice::Clear(ClearOptions options, Color const& color, float depth, Int stencil) const { + if (!Implementation) 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); + + Implementation->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) { + Implementation = unew(); + adapter = graphicsAdapter; + presentationParameters = parameters; + + Initialize(); + } + + // + // INTERNAL + // + static void initAndApplyState(P_BlendState& blendState, P_RasterizerState& rasterizerState, P_DepthStencilState& depthStencilState, P_SamplerStateCollection& samplerStates, P_GraphicsDevice const& device) { blendState->Bind(device); blendState->Initialize();