#include "xna/platform-dx/dx.hpp" #include "xna/game/gdevicemanager.hpp" namespace xna { static void reset(GraphicsDevice::PlatformImplementation& 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; } } static void createDevice(GraphicsDevice::PlatformImplementation& impl) { auto createDeviceFlags = 0; #if _DEBUG createDeviceFlags = D3D11_CREATE_DEVICE_FLAG::D3D11_CREATE_DEVICE_DEBUG; #endif auto hr = D3D11CreateDevice( impl._adapter->impl->dxadapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, createDeviceFlags, NULL, 0, D3D11_SDK_VERSION, &impl._device, &impl._featureLevel, &impl._context); if (FAILED(hr)) { OutputDebugString("---> Usando Adaptador WARP: não há suporte ao D3D11\n"); hr = D3D11CreateDevice( NULL, D3D_DRIVER_TYPE_WARP, NULL, createDeviceFlags, NULL, 0, D3D11_SDK_VERSION, &impl._device, &impl._featureLevel, &impl._context); if FAILED(hr) Exception::Throw(ExMessage::CreateComponent); } } GraphicsDevice::GraphicsDevice() { impl = unew(); impl->_adapter = GraphicsAdapter::DefaultAdapter(); impl->_adapter->CurrentDisplayMode( SurfaceFormat::Color, GraphicsDeviceManager::DefaultBackBufferWidth, GraphicsDeviceManager::DefaultBackBufferHeight); } GraphicsDevice::GraphicsDevice(GraphicsDeviceInformation const& info) { impl = unew(); impl->_adapter = info.Adapter; impl->_gameWindow = info.Window; impl->_presentationParameters = info.Parameters; impl->_adapter->CurrentDisplayMode( impl->_presentationParameters->BackBufferFormat, impl->_presentationParameters->BackBufferWidth, impl->_presentationParameters->BackBufferHeight); } 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(ExMessage::CreateComponent); const auto bounds = impl->_gameWindow->ClientBounds(); impl->_viewport = xna::Viewport(0.0F, 0.0F, static_cast(bounds.Width), static_cast(bounds.Height), 0.0F, 1.F); COLORREF color = impl->_gameWindow->impl->Color(); impl->_backgroundColor[0] = GetRValue(color) / 255.0f; impl->_backgroundColor[1] = GetGValue(color) / 255.0f; impl->_backgroundColor[2] = GetBValue(color) / 255.0f; impl->_backgroundColor[3] = 1.0f; impl->_swapChain = snew(_this); impl->_swapChain->Initialize(); hr = impl->_factory->MakeWindowAssociation(impl->_gameWindow->impl->WindowHandle(), DXGI_MWA_NO_ALT_ENTER); if (FAILED(hr)) Exception::Throw(ExMessage::MakeWindowAssociation); 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); impl->InitializeAndApplyStates(_this); return true; } bool GraphicsDevice::Present() { if (!impl) return false; const auto result = impl->_swapChain->Present(impl->_usevsync); impl->_context->OMSetRenderTargets(1, &impl->_renderTarget2D->render_impl->_renderTargetView, nullptr); return result; } void GraphicsDevice::Clear() { if (!impl) return; impl->_context->ClearRenderTargetView(impl->_renderTarget2D->render_impl->_renderTargetView, impl->_backgroundColor); } void GraphicsDevice::Clear(Color const& color) { 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, impl->_backgroundColor); } 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 use) { if (!impl) return; impl->_usevsync = use; } 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; } }