1
0
mirror of https://github.com/borgesdan/xn65 synced 2024-12-29 21:54:47 +01:00

282 lines
7.5 KiB
C++
Raw Permalink Normal View History

2024-07-13 22:55:36 -03:00
#include "xna/xna-dx.hpp"
2024-03-18 15:41:46 -03:00
namespace xna {
2024-08-02 16:40:06 -03:00
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);
2024-06-25 15:41:11 -03:00
GraphicsDevice::GraphicsDevice() {
2024-05-24 22:26:10 -03:00
impl = unew<PlatformImplementation>();
2024-08-02 16:40:06 -03:00
adapter = GraphicsAdapter::DefaultAdapter();
}
2024-08-02 16:40:06 -03:00
GraphicsDevice::GraphicsDevice(sptr<GraphicsAdapter> const& adapter, GraphicsProfile const& graphicsProfile, sptr<PresentationParameters> const& presentationParameters)
: adapter(adapter), graphicsProfile(graphicsProfile), presentationParameters(presentationParameters) {
2024-05-24 22:26:10 -03:00
impl = unew<PlatformImplementation>();
2024-08-02 16:40:06 -03:00
blendState = xna::BlendState::Opaque();
depthStencilState = xna::DepthStencilState::Default();
rasterizerState = xna::RasterizerState::CullCounterClockwise();
samplerStateCollection = snew<SamplerStateCollection>();
2024-07-30 21:56:17 -03:00
}
2024-08-02 16:40:06 -03:00
void GraphicsDevice::Initialize() {
reset(*impl);
auto _this = shared_from_this();
createDevice(*impl, *adapter);
2024-08-02 16:40:06 -03:00
//
// Background
//
2024-07-30 21:56:17 -03:00
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;
2024-03-18 15:41:46 -03:00
//
// Window Association
//
auto hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&impl->_factory);
if FAILED(hr)
Exception::Throw(Exception::FAILED_TO_CREATE);
2024-03-18 15:41:46 -03:00
2024-08-02 16:40:06 -03:00
auto hwnd = reinterpret_cast<HWND>(presentationParameters->DeviceWindowHandle);
2024-07-30 21:56:17 -03:00
hr = impl->_factory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER);
if (FAILED(hr))
2024-08-02 16:40:06 -03:00
Exception::Throw(Exception::FAILED_TO_MAKE_WINDOW_ASSOCIATION);
//
// Viewport
//
viewport = xna::Viewport(0.0F, 0.0F,
presentationParameters->BackBufferWidth,
presentationParameters->BackBufferHeight,
0.0F, 1.F);
2024-03-18 15:41:46 -03:00
2024-08-02 16:40:06 -03:00
D3D11_VIEWPORT view = DxHelpers::ViewportToDx(viewport);
2024-05-24 22:26:10 -03:00
impl->_context->RSSetViewports(1, &view);
2024-03-18 15:41:46 -03:00
//
// States
//
2024-08-02 16:40:06 -03:00
initAndApplyState(blendState, rasterizerState, depthStencilState, samplerStateCollection, _this);
2024-03-18 15:41:46 -03:00
//
// Presentation
//
2024-08-02 16:40:06 -03:00
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;
2024-08-02 16:40:06 -03:00
}
impl->_swapChain = snew<xna::SwapChain>(_this);
impl->_swapChain->Initialize();
//
//Render Target
//
if (renderTarget) {
renderTarget->Initialize();
impl->_renderTarget2D = renderTarget;
}
else {
impl->_renderTarget2D = RenderTarget2D::FromBackBuffer(_this);
}
const auto& renderView = impl->_renderTarget2D->impl2->_renderTargetView;
impl->_context->OMSetRenderTargets(1, renderView.GetAddressOf(), nullptr);
}
2024-03-18 15:41:46 -03:00
bool GraphicsDevice::Present() const {
bool result = impl->_swapChain->Present(impl->vSyncValue != 0);
2024-06-25 17:06:37 -03:00
impl->_context->OMSetRenderTargets(
1,
impl->_renderTarget2D->impl2->_renderTargetView.GetAddressOf(),
2024-06-25 17:06:37 -03:00
nullptr);
2024-03-18 15:41:46 -03:00
return result;
2024-06-25 15:41:11 -03:00
}
void GraphicsDevice::Clear(Color const& color) const {
2024-05-24 22:26:10 -03:00
if (!impl) return;
2024-05-24 22:26:10 -03:00
const auto v4 = color.ToVector4();
2024-04-22 11:22:18 -03:00
2024-05-24 22:26:10 -03:00
impl->_backgroundColor[0] = v4.X;
impl->_backgroundColor[1] = v4.Y;
impl->_backgroundColor[2] = v4.Z;
impl->_backgroundColor[3] = v4.W;
2024-06-25 15:41:11 -03:00
2024-05-24 22:26:10 -03:00
impl->_context->ClearRenderTargetView(
impl->_renderTarget2D->impl2->_renderTargetView.Get(),
2024-05-24 22:26:10 -03:00
impl->_backgroundColor);
}
2024-03-18 15:41:46 -03:00
2024-08-02 16:40:06 -03:00
void GraphicsDevice::Clear(ClearOptions options, Color const& color, float depth, Int stencil) const {
2024-06-25 15:41:11 -03:00
if (!impl) return;
switch (options)
{
case xna::ClearOptions::DepthBuffer:
2024-07-06 12:20:54 -03:00
Exception::Throw(Exception::NOT_IMPLEMENTED);
2024-06-25 15:41:11 -03:00
break;
case xna::ClearOptions::Stencil:
2024-07-06 12:20:54 -03:00
Exception::Throw(Exception::NOT_IMPLEMENTED);
2024-06-25 15:41:11 -03:00
break;
case xna::ClearOptions::Target:
Clear(color);
break;
default:
return;
}
2024-08-02 16:40:06 -03:00
}
2024-06-25 15:41:11 -03:00
2024-08-02 16:40:06 -03:00
void GraphicsDevice::Viewport(xna::Viewport const& value) {
viewport = value;
const auto view = DxHelpers::ViewportToDx(viewport);
2024-06-25 15:41:11 -03:00
2024-08-02 16:40:06 -03:00
impl->_context->RSSetViewports(1, &view);
}
void GraphicsDevice::BlendState(sptr<xna::BlendState> const& value) {
blendState = value;
blendState->Apply();
}
void GraphicsDevice::DepthStencilState(sptr<xna::DepthStencilState> const& value) {
depthStencilState = value;
depthStencilState->Apply();
2024-06-25 15:41:11 -03:00
}
2024-08-02 16:40:06 -03:00
void GraphicsDevice::RasterizerState(sptr<xna::RasterizerState> const& value) {
rasterizerState = value;
rasterizerState->Apply();
}
2024-06-25 15:41:11 -03:00
2024-08-02 16:40:06 -03:00
void GraphicsDevice::Reset(sptr<PresentationParameters> const& parameters, sptr<GraphicsAdapter> const& graphicsAdapter){
impl = unew<PlatformImplementation>();
adapter = graphicsAdapter;
presentationParameters = parameters;
Initialize();
}
2024-08-02 16:40:06 -03:00
//
// INTERNAL
//
2024-03-18 15:41:46 -03:00
2024-08-02 16:40:06 -03:00
void reset(GraphicsDevice::PlatformImplementation& impl)
{
if (impl._device) {
impl._device->Release();
impl._device = nullptr;
}
if (impl._context) {
impl._context->Release();
impl._context = nullptr;
}
2024-03-18 15:41:46 -03:00
2024-08-02 16:40:06 -03:00
if (impl._factory) {
impl._factory->Release();
impl._factory = nullptr;
}
2024-05-24 22:26:10 -03:00
}
2024-03-18 15:41:46 -03:00
2024-08-02 16:40:06 -03:00
void createDevice(GraphicsDevice::PlatformImplementation& impl, 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
//
2024-03-21 16:01:47 -03:00
2024-08-02 16:40:06 -03:00
auto createDeviceFlags = 0;
#if _DEBUG
createDeviceFlags = D3D11_CREATE_DEVICE_FLAG::D3D11_CREATE_DEVICE_DEBUG;
#endif
2024-05-24 22:26:10 -03:00
2024-08-02 16:40:06 -03:00
const auto& pAdapter = GraphicsAdapter::UseNullDevice() ? NULL : currentAdapter.impl->dxAdapter.Get();
2024-05-24 22:26:10 -03:00
2024-08-02 16:40:06 -03:00
//
// if pAdapter is not NULL driverType must be D3D_DRIVER_TYPE_UNKNOWN
//
auto driverType = D3D_DRIVER_TYPE_UNKNOWN;
2024-06-24 15:11:07 -03:00
2024-08-02 16:40:06 -03:00
if (GraphicsAdapter::UseReferenceDevice())
driverType = D3D_DRIVER_TYPE_WARP;
else if (GraphicsAdapter::UseNullDevice())
driverType = D3D_DRIVER_TYPE_HARDWARE;
2024-06-24 15:11:07 -03:00
2024-08-02 16:40:06 -03:00
auto hr = D3D11CreateDevice(
//_In_opt_ IDXGIAdapter* pAdapter,
pAdapter,
//D3D_DRIVER_TYPE DriverType,
driverType,
//HMODULE Software,
NULL,
//UINT Flags,
createDeviceFlags,
//_In_reads_opt_( FeatureLevels ) CONST D3D_FEATURE_LEVEL* pFeatureLevels,
impl.featureLevels,
//UINT FeatureLevels,
7,
//UINT SDKVersion,
D3D11_SDK_VERSION,
//_COM_Outptr_opt_ ID3D11Device** ppDevice
impl._device.GetAddressOf(),
//_Out_opt_ D3D_FEATURE_LEVEL* pFeatureLevel,
&impl.currentFeatureLevel,
//_COM_Outptr_opt_ ID3D11DeviceContext** ppImmediateContext
impl._context.GetAddressOf());
2024-06-24 15:11:07 -03:00
2024-08-02 16:40:06 -03:00
if FAILED(hr)
Exception::Throw(Exception::FAILED_TO_CREATE);
2024-06-24 15:11:07 -03:00
}
2024-08-02 16:40:06 -03:00
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();
2024-08-02 16:40:06 -03:00
rasterizerState->Bind(device);
rasterizerState->Initialize();
rasterizerState->Apply();
depthStencilState->Bind(device);
depthStencilState->Initialize();
depthStencilState->Apply();
samplerStates->Apply(*device);
}
2024-03-18 15:41:46 -03:00
}