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

Merge pull request #13 from borgesdan/develop

Implementações em GraphicsDeviceManager
This commit is contained in:
Danilo Borges 2024-07-31 17:58:30 -03:00 committed by GitHub
commit aa99c4d950
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 1383 additions and 708 deletions

View File

@ -23,6 +23,6 @@ project ("xna")
include_directories(${PROJECT_INCLUDES_DIR})
add_subdirectory ("framework")
#add_subdirectory ("samples")
add_subdirectory ("samples")

View File

@ -40,7 +40,7 @@ add_library (Xn65 STATIC
"platform-dx/audioengine.cpp"
"graphics/gresource.cpp"
"platform-dx/effect.cpp"
"exception.cpp")
"exception.cpp" "platform-dx/screen.cpp" )
if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET Xn65 PROPERTY CXX_STANDARD 20)

View File

@ -1,11 +1,11 @@
#include "xna/graphics/adapter.hpp"
#include "xna/graphics/displaymode.hpp"
#include "xna/game/gdevicemanager.hpp"
#include "xna/xna-dx.hpp"
namespace xna {
namespace xna {
static void setOutputVars(comptr<IDXGIAdapter1> const& adapter, String& deviceName, intptr_t& monitorHandle);
static size_t getDisplayModesCount(IDXGIAdapter* adapter);
static uptr<DisplayModeCollection> createDisplayModeCollection(std::vector<DXGI_MODE_DESC> const& source);
static sptr<DisplayModeCollection> createDisplayModeCollection(std::vector<DXGI_MODE_DESC1> const& source);
static void setCurrentDisplayMode(DisplayModeCollection& displayModes, SurfaceFormat surfaceFormat, Uint width, Uint height, sptr<DisplayMode>& currentDisplayMode);
static sptr<DisplayModeCollection> getSupportedDisplayModes(comptr<IDXGIAdapter1>& dxAdapter);
GraphicsAdapter::GraphicsAdapter() {
impl = unew<PlatformImplementation>();
@ -18,12 +18,32 @@ namespace xna {
Exception::Throw(Exception::FAILED_TO_CREATE);
comptr<IDXGIAdapter1> pAdapter = nullptr;
if (pFactory->EnumAdapters1(0, pAdapter.GetAddressOf()) != DXGI_ERROR_NOT_FOUND) {
auto adp = unew<GraphicsAdapter>();
adp->impl->_index = 0;
adp->impl->dxadapter = pAdapter;
if (pFactory->EnumAdapters1(0, pAdapter.GetAddressOf()) != DXGI_ERROR_NOT_FOUND) {
auto adp = uptr<GraphicsAdapter>(new GraphicsAdapter());
adp->impl->dxAdapter = pAdapter;
adp->impl->dxFactory = pFactory;
DXGI_ADAPTER_DESC1 desc{};
pAdapter->GetDesc1(&desc);
adp->description = XnaHelper::ToString(desc.Description);
adp->deviceId = static_cast<Uint>(desc.DeviceId);
adp->isDefault = true;
adp->revision = static_cast<Uint>(desc.Revision);
adp->subSystemId = static_cast<Uint>(desc.SubSysId);
adp->vendorId = static_cast<Uint>(desc.VendorId);
setOutputVars(pAdapter, adp->deviceName, adp->monitorHandle);
adp->supportedDisplayModes = getSupportedDisplayModes(pAdapter);
if (adp->supportedDisplayModes && adp->supportedDisplayModes->Count() > 0) {
setCurrentDisplayMode(*adp->supportedDisplayModes, SurfaceFormat::Color,
GraphicsDeviceManager::DefaultBackBufferWidth,
GraphicsDeviceManager::DefaultBackBufferHeight, adp->currentDisplayMode);
}
return adp;
}
@ -38,247 +58,185 @@ namespace xna {
Exception::Throw(Exception::FAILED_TO_CREATE);
comptr<IDXGIAdapter1> pAdapter = nullptr;
UINT count = 0;
for (; pFactory->EnumAdapters1(count, pAdapter.GetAddressOf()) != DXGI_ERROR_NOT_FOUND; ++count) {
auto adp = unew<GraphicsAdapter>();
for (UINT count = 0; pFactory->EnumAdapters1(count, pAdapter.GetAddressOf()) != DXGI_ERROR_NOT_FOUND; ++count) {
auto adp = uptr<GraphicsAdapter>(new GraphicsAdapter());
adp->impl->_index = count;
adp->impl->dxadapter = pAdapter;
adp->impl->dxAdapter = pAdapter;
adp->impl->dxFactory = pFactory;
DXGI_ADAPTER_DESC1 desc{};
pAdapter->GetDesc1(&desc);
adp->description = XnaHelper::ToString(desc.Description);
adp->deviceId = static_cast<Uint>(desc.DeviceId);
adp->isDefault = count == 0;
adp->revision = static_cast<Uint>(desc.Revision);
adp->subSystemId = static_cast<Uint>(desc.SubSysId);
adp->vendorId = static_cast<Uint>(desc.VendorId);
setOutputVars(pAdapter, adp->deviceName, adp->monitorHandle);
adp->supportedDisplayModes = getSupportedDisplayModes(pAdapter);
if (adp->supportedDisplayModes && adp->supportedDisplayModes->Count() > 0) {
setCurrentDisplayMode(*adp->supportedDisplayModes, SurfaceFormat::Color,
GraphicsDeviceManager::DefaultBackBufferWidth,
GraphicsDeviceManager::DefaultBackBufferHeight, adp->currentDisplayMode);
}
adapters.push_back(std::move(adp));
}
}
String GraphicsAdapter::Description() const {
if (!impl->dxadapter) return String();
DXGI_ADAPTER_DESC1 desc;
impl->dxadapter->GetDesc1(&desc);
String description = XnaHelper::ToString(desc.Description);
return description;
}
Uint GraphicsAdapter::DeviceId() const {
if (!impl->dxadapter) return 0;
DXGI_ADAPTER_DESC1 desc;
impl->dxadapter->GetDesc1(&desc);
return static_cast<Uint>(desc.DeviceId);
}
String GraphicsAdapter::DeviceName() const {
if (!impl->dxadapter) return String();
IDXGIOutput* pOutput = nullptr;
DXGI_OUTPUT_DESC outputDesc;
if (impl->dxadapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
pOutput->GetDesc(&outputDesc);
String deviceName = XnaHelper::ToString(outputDesc.DeviceName);
pOutput->Release();
pOutput = nullptr;
return deviceName;
}
return String();
}
intptr_t GraphicsAdapter::MonitorHandle() const {
if (!impl->dxadapter) return 0;
IDXGIOutput* pOutput = nullptr;
DXGI_OUTPUT_DESC outputDesc;
if (impl->dxadapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
pOutput->GetDesc(&outputDesc);
pOutput->Release();
pOutput = nullptr;
return reinterpret_cast<intptr_t>(outputDesc.Monitor);
}
return 0;
}
Uint GraphicsAdapter::Revision() const {
if (!impl->dxadapter) return 0;
DXGI_ADAPTER_DESC1 desc;
impl->dxadapter->GetDesc1(&desc);
return static_cast<Uint>(desc.Revision);
}
Uint GraphicsAdapter::SubSystemId() const {
if (!impl->dxadapter) return 0;
DXGI_ADAPTER_DESC1 desc;
impl->dxadapter->GetDesc1(&desc);
return static_cast<Uint>(desc.SubSysId);
}
Uint GraphicsAdapter::VendorId() const {
if (!impl->dxadapter) return 0;
DXGI_ADAPTER_DESC1 desc;
impl->dxadapter->GetDesc1(&desc);
return static_cast<Uint>(desc.VendorId);
}
uptr<DisplayModeCollection> GraphicsAdapter::SupportedDisplayModes() const {
if (!impl->dxadapter) return nullptr;
const auto totalDisplay = getDisplayModesCount(impl->dxadapter.Get());
if (totalDisplay == 0)
return nullptr;
IDXGIOutput* pOutput = nullptr;
UINT bufferOffset = 0;
std::vector<DXGI_MODE_DESC> buffer(totalDisplay);
if (impl->dxadapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) {
const auto currentSurface = static_cast<SurfaceFormat>(f);
DXGI_FORMAT format = DxHelpers::SurfaceFormatToDx(currentSurface);
UINT numModes = 0;
pOutput->GetDisplayModeList(format, 0, &numModes, nullptr);
if (numModes == 0)
continue;
pOutput->GetDisplayModeList(format, 0, &numModes, buffer.data() + bufferOffset);
bufferOffset += numModes;
}
}
if (!pOutput)
return nullptr;
pOutput->Release();
pOutput = nullptr;
return createDisplayModeCollection(buffer);
}
uptr<DisplayModeCollection> GraphicsAdapter::SupportedDisplayModes(SurfaceFormat surfaceFormat) const
bool GraphicsAdapter::QueryBackBufferFormat(
GraphicsProfile graphicsProfile, SurfaceFormat format,
DepthFormat depthFormat, Int multiSampleCount,
SurfaceFormat& selectedFormat, DepthFormat& selectedDepthFormat,
Int& selectedMultiSampleCount) const
{
if (!impl->dxadapter) return nullptr;
selectedFormat = format;
selectedDepthFormat = depthFormat;
selectedMultiSampleCount = multiSampleCount;
IDXGIOutput* pOutput = nullptr;
UINT bufferOffset = 0;
comptr<IDXGIOutput> pOutput = nullptr;
if (impl->dxadapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
DXGI_FORMAT format = DxHelpers::SurfaceFormatToDx(surfaceFormat);
if (impl->dxAdapter->EnumOutputs(0, pOutput.GetAddressOf()) != DXGI_ERROR_NOT_FOUND){
comptr<IDXGIOutput1> pOutput1 = nullptr;
UINT numModes = 0;
pOutput->QueryInterface(IID_IDXGIOutput1, (void**)pOutput1.GetAddressOf());
pOutput->GetDisplayModeList(format, 0, &numModes, nullptr);
DXGI_MODE_DESC1 modeToMath{};
modeToMath.Format = DxHelpers::SurfaceFormatToDx(format);
if (numModes == 0)
return unew<DisplayModeCollection>();
//If pConcernedDevice is NULL, the Format member of DXGI_MODE_DESC1 cannot be DXGI_FORMAT_UNKNOWN.
if (modeToMath.Format == DXGI_FORMAT_UNKNOWN)
return false;
std::vector<DXGI_MODE_DESC> buffer(numModes);
pOutput->GetDisplayModeList(format, 0, &numModes, buffer.data());
DXGI_MODE_DESC1 closestMath;
const auto hresult = pOutput1->FindClosestMatchingMode1(&modeToMath, &closestMath, nullptr);
pOutput->Release();
pOutput = nullptr;
if FAILED(hresult)
return false;
return createDisplayModeCollection(buffer);
}
selectedFormat = DxHelpers::SurfaceFormatToXna(closestMath.Format);
return unew<DisplayModeCollection>();
}
sptr<DisplayMode> GraphicsAdapter::CurrentDisplayMode() {
if (!impl->_currentDisplayMode) {
CurrentDisplayMode(SurfaceFormat::Color, GraphicsDeviceManager::DefaultBackBufferWidth, GraphicsDeviceManager::DefaultBackBufferHeight);
return selectedFormat == format;
}
return impl->_currentDisplayMode;
}
void GraphicsAdapter::CurrentDisplayMode(SurfaceFormat surfaceFormat, Uint width, Uint height) {
const auto modes = SupportedDisplayModes(surfaceFormat);
for (size_t i = 0; i < modes->DisplayModes.size(); ++i) {
auto& m = modes->DisplayModes[i];
if (m->Format == surfaceFormat && m->Width == width && m->Height == height) {
impl->_currentDisplayMode = m;
}
else if(i + 1 == modes->DisplayModes.size()) {
impl->_currentDisplayMode = m;
}
}
}
bool GraphicsAdapter::PlatformImplementation::GetOutput(UINT slot, IDXGIOutput*& output) {
if (!dxadapter) return false;
if (dxadapter->EnumOutputs(slot, &output) != DXGI_ERROR_NOT_FOUND)
return true;
return false;
}
//INTERNAL FUNCTIONS
static size_t getDisplayModesCount(IDXGIAdapter* adapter) {
IDXGIOutput* pOutput = nullptr;
size_t numModes = 0;
sptr<DisplayModeCollection> getSupportedDisplayModes(comptr<IDXGIAdapter1>& dxAdapter) {
const auto totalDisplay = getDisplayModesCount(dxAdapter.Get());
if (adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) {
if (totalDisplay == 0)
return nullptr;
comptr<IDXGIOutput> pOutput = nullptr;
comptr<IDXGIOutput1> pOutput1 = nullptr;
UINT bufferOffset = 0;
std::vector<DXGI_MODE_DESC1> buffer(totalDisplay);
if (dxAdapter->EnumOutputs(0, pOutput.GetAddressOf()) != DXGI_ERROR_NOT_FOUND) {
for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) {
const auto currentSurface = static_cast<SurfaceFormat>(f);
DXGI_FORMAT format = DxHelpers::SurfaceFormatToDx(currentSurface);
UINT numModes = 0;
if (!pOutput1) {
pOutput->QueryInterface(IID_IDXGIOutput1, (void**)pOutput1.GetAddressOf());
}
//See ref: https://learn.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgioutput-getdisplaymodelist?redirectedfrom=MSDN
pOutput1->GetDisplayModeList1(format, 0, &numModes, nullptr);
if (numModes == 0)
continue;
pOutput1->GetDisplayModeList1(format, 0, &numModes, buffer.data() + bufferOffset);
bufferOffset += numModes;
}
}
if (!pOutput)
return nullptr;
return createDisplayModeCollection(buffer);
}
void setCurrentDisplayMode(DisplayModeCollection& displayModes, SurfaceFormat surfaceFormat, Uint width, Uint height, sptr<DisplayMode>& currentDisplayMode) {
auto modes = displayModes.Query(surfaceFormat);
for (size_t i = 0; i < modes.size(); ++i) {
auto& m = modes[i];
if (m->Format() == surfaceFormat && m->Width() == width && m->Height() == height) {
currentDisplayMode = m;
}
else if (i + 1 == modes.size()) {
currentDisplayMode = m;
}
}
}
size_t getDisplayModesCount(IDXGIAdapter* adapter) {
comptr<IDXGIOutput> pOutput = nullptr;
comptr<IDXGIOutput1> pOutput1 = nullptr;
size_t numModes = 0;
if (adapter->EnumOutputs(0, pOutput.GetAddressOf()) != DXGI_ERROR_NOT_FOUND) {
for (size_t f = 0; f < SURFACE_FORMAT_COUNT; ++f) {
const auto currentSurface = static_cast<SurfaceFormat>(f);
DXGI_FORMAT format = DxHelpers::SurfaceFormatToDx(currentSurface);
UINT num = 0;
pOutput->GetDisplayModeList(format, 0, &num, nullptr);
if (!pOutput1) {
pOutput->QueryInterface(IID_IDXGIOutput1, (void**)pOutput1.GetAddressOf());
}
//See ref: https://learn.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgioutput-getdisplaymodelist?redirectedfrom=MSDN
pOutput1->GetDisplayModeList1(format, 0, &num, nullptr);
numModes += num;
}
pOutput->Release();
pOutput = nullptr;
}
return numModes;
}
static uptr<DisplayModeCollection> createDisplayModeCollection(std::vector<DXGI_MODE_DESC> const& source) {
auto collection = unew<DisplayModeCollection>();
DisplayMode currentDisplayMode;
sptr<DisplayModeCollection> createDisplayModeCollection(std::vector<DXGI_MODE_DESC1> const& source) {
auto collection = snew<DisplayModeCollection>();
std::vector<sptr<DisplayMode>> displayList;
sptr<DisplayMode> pDisplay = nullptr;
for (size_t i = 0; i < source.size(); ++i) {
auto& modedesc = source[i];
DisplayModeDescription description;
description._refreshRate = modedesc.RefreshRate;
description._scaling = static_cast<DisplayModeScaling>(modedesc.Scaling);
description._scanlineOrdering = static_cast<DisplayModeScanlineOrder>(modedesc.ScanlineOrdering);
DisplayModeRate rate;
rate.RefreshRate.Denominator = modedesc.RefreshRate.Denominator;
rate.RefreshRate.Numerator = modedesc.RefreshRate.Numerator;
rate.Scaling = static_cast<DisplayModeScaling>(modedesc.Scaling);
rate.ScanlineOrdering = static_cast<DisplayModeScanlineOrder>(modedesc.ScanlineOrdering);
if (pDisplay && pDisplay->Width == modedesc.Width && pDisplay->Height == modedesc.Height && pDisplay->Format == DxHelpers::SurfaceFormatToXna(modedesc.Format)) {
pDisplay->impl->Descriptions.push_back(description);
if (pDisplay && pDisplay->Width() == modedesc.Width && pDisplay->Height() == modedesc.Height && pDisplay->Format() == DxHelpers::SurfaceFormatToXna(modedesc.Format)) {
pDisplay->Rates.push_back(rate);
}
else {
pDisplay = snew<DisplayMode>();
pDisplay->Width = modedesc.Width;
pDisplay->Height = modedesc.Height;
pDisplay->Format = DxHelpers::SurfaceFormatToXna(modedesc.Format);
pDisplay->impl->Descriptions.push_back(description);
pDisplay = snew<DisplayMode>(
modedesc.Width,
modedesc.Height,
DxHelpers::SurfaceFormatToXna(modedesc.Format));
pDisplay->Rates.push_back(rate);
displayList.push_back(pDisplay);
}
}
@ -286,5 +244,17 @@ namespace xna {
collection->DisplayModes = displayList;
return collection;
}
static void setOutputVars(comptr<IDXGIAdapter1> const& adapter, String& deviceName, intptr_t& monitorHandle) {
comptr<IDXGIOutput> pOutput = nullptr;
if (adapter->EnumOutputs(0, pOutput.GetAddressOf()) != DXGI_ERROR_NOT_FOUND) {
DXGI_OUTPUT_DESC outputDesc;
pOutput->GetDesc(&outputDesc);
deviceName = XnaHelper::ToString(outputDesc.DeviceName);
monitorHandle = reinterpret_cast<intptr_t>(outputDesc.Monitor);
}
}
}

View File

@ -21,43 +21,61 @@ namespace xna {
}
static void createDevice(GraphicsDevice::PlatformImplementation& impl) {
//
// 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
//
auto createDeviceFlags = 0;
#if _DEBUG
createDeviceFlags = D3D11_CREATE_DEVICE_FLAG::D3D11_CREATE_DEVICE_DEBUG;
#endif
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
//
auto driverType = D3D_DRIVER_TYPE_UNKNOWN;
if (GraphicsAdapter::UseReferenceDevice())
driverType = D3D_DRIVER_TYPE_WARP;
else if (GraphicsAdapter::UseNullDevice())
driverType = D3D_DRIVER_TYPE_HARDWARE;
auto hr = D3D11CreateDevice(
impl._adapter->impl->dxadapter.Get(),
D3D_DRIVER_TYPE_UNKNOWN,
//_In_opt_ IDXGIAdapter* pAdapter,
pAdapter,
//D3D_DRIVER_TYPE DriverType,
driverType,
//HMODULE Software,
NULL,
//UINT Flags,
createDeviceFlags,
NULL,
0,
//_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(),
&impl._featureLevel,
//_Out_opt_ D3D_FEATURE_LEVEL* pFeatureLevel,
&impl.currentFeatureLevel,
//_COM_Outptr_opt_ ID3D11DeviceContext** ppImmediateContext
impl._context.GetAddressOf());
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.GetAddressOf(),
&impl._featureLevel,
impl._context.GetAddressOf());
if FAILED(hr)
Exception::Throw(Exception::FAILED_TO_CREATE);
}
if FAILED(hr)
Exception::Throw(Exception::FAILED_TO_CREATE);
}
void initAndApplyState(GraphicsDevice::PlatformImplementation& impl, PGraphicsDevice const& device) {
static void initAndApplyState(GraphicsDevice::PlatformImplementation& impl, PGraphicsDevice const& device) {
impl._blendState->Bind(device);
impl._blendState->Initialize();
impl._blendState->Apply();
@ -75,25 +93,22 @@ namespace xna {
GraphicsDevice::GraphicsDevice() {
impl = unew<PlatformImplementation>();
impl->_adapter = GraphicsAdapter::DefaultAdapter();
impl->_adapter->CurrentDisplayMode(
SurfaceFormat::Color,
GraphicsDeviceManager::DefaultBackBufferWidth,
GraphicsDeviceManager::DefaultBackBufferHeight);
impl->_adapter = GraphicsAdapter::DefaultAdapter();
}
GraphicsDevice::GraphicsDevice(GraphicsDeviceInformation const& info) {
impl = unew<PlatformImplementation>();
impl->_adapter = info.Adapter;
impl->_gameWindow = info.Window;
impl->_presentationParameters = info.Parameters;
impl->_adapter->CurrentDisplayMode(
impl->_presentationParameters->BackBufferFormat,
impl->_presentationParameters->BackBufferWidth,
impl->_presentationParameters->BackBufferHeight);
impl->_presentationParameters = info.PresentParameters;
}
GraphicsDevice::GraphicsDevice(sptr<GraphicsAdapter> const& adapter, GraphicsProfile const& graphicsProfile, sptr<PresentationParameters> const& presentationParameters) {
impl = unew<PlatformImplementation>();
impl->_adapter = adapter;
impl->_presentationParameters = presentationParameters;
}
bool GraphicsDevice::Initialize() {
auto _this = shared_from_this();
@ -109,23 +124,27 @@ namespace xna {
if FAILED(hr)
Exception::Throw(Exception::FAILED_TO_CREATE);
const auto bounds = impl->_gameWindow->ClientBounds();
//const auto bounds = impl->_gameWindow->ClientBounds();
impl->_viewport = xna::Viewport(0.0F, 0.0F,
static_cast<float>(bounds.Width),
static_cast<float>(bounds.Height),
impl->_presentationParameters->BackBufferWidth,
impl->_presentationParameters->BackBufferHeight,
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;
//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<xna::SwapChain>(_this);
impl->_swapChain->Initialize();
hr = impl->_factory->MakeWindowAssociation(impl->_gameWindow->impl->WindowHandle(), DXGI_MWA_NO_ALT_ENTER);
auto hwnd = reinterpret_cast<HWND>(impl->_presentationParameters->DeviceWindowHandle);
hr = impl->_factory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER);
if (FAILED(hr))
Exception::Throw(Exception::FAILED_TO_MAKE_WINDOW_ASSOCIATION);
@ -264,4 +283,12 @@ namespace xna {
void GraphicsDevice::MultiSampleMask(Int value) {
impl->_multiSampleMask = value;
}
void GraphicsDevice::Reset(sptr<PresentationParameters> const& presentationParameters, sptr<GraphicsAdapter> const& graphicsAdapter){
impl = unew<PlatformImplementation>();
impl->_adapter = graphicsAdapter;
impl->_presentationParameters = presentationParameters;
Initialize();
}
}

View File

@ -2,16 +2,12 @@
#include "xna/graphics/displaymode.hpp"
namespace xna {
DisplayMode::DisplayMode() {
impl = unew<PlatformImplementation>();
}
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) {
if (DisplayModes[i]->Format() == format) {
++counter;
}
}
@ -27,7 +23,7 @@ namespace xna {
std::vector<sptr<DisplayMode>> modes(count);
for (size_t i = 0; i < DisplayModes.size(); ++i) {
if (DisplayModes[i]->Format == format) {
if (DisplayModes[i]->Format() == format) {
modes[index] = DisplayModes[i];
++index;
}
@ -46,10 +42,10 @@ namespace xna {
for (size_t i = 0; i < DisplayModes.size(); ++i) {
const auto& mode = DisplayModes[i];
if (mode->Format == format && mode->Width == width && mode->Height == height) {
if (mode->Format() == format && mode->Width() == width && mode->Height() == height) {
return DisplayModes[i];
}
else if(mode->Format == format && mode->Width == width) {
else if(mode->Format() == format && mode->Width() == width) {
matched = mode;
}
}

View File

@ -30,7 +30,7 @@ namespace xna {
}
void BasicEffect::Alpha(float value) {
const auto a = MathHelper::Clamp(value, 0.0f, 1.0);
const auto a = MathHelper::Clamp(value, 0.0F, 1.0F);
impl->dxBasicEffect->SetAlpha(a);
}
@ -116,7 +116,7 @@ namespace xna {
void BasicEffect::SetDirectionalLight(Int index, DirectionalLight const& direction) {
DxVec vec3 = DxHelpers::VectorToDx(direction.Direction);
const auto value = (int)MathHelper::Clamp(index, 0, impl->dxBasicEffect->MaxDirectionalLights);
const auto value = MathHelper::Clamp(index, 0, impl->dxBasicEffect->MaxDirectionalLights);
impl->dxBasicEffect->SetLightDirection(value, vec3);
}

View File

@ -64,7 +64,12 @@ namespace xna {
int Game::Run() {
try {
Initialize();
if (!_gameWindow->impl->Create()) {
Exception::Throw(Exception::FAILED_TO_CREATE);
return false;
}
Initialize();
if (graphicsDevice == nullptr) {
MessageBox(nullptr, "O dispositivo gráfico não foi inicializado corretamente", "XN65", MB_OK);

View File

@ -1,41 +1,35 @@
#include "xna/game/gdevicemanager.hpp"
#include "xna/graphics/presentparams.hpp"
#include "xna/graphics/swapchain.hpp"
#include "xna/xna-dx.hpp"
namespace xna {
GraphicsDeviceManager::GraphicsDeviceManager(sptr<Game> const& game) : _game(game)
static bool IsWindowOnAdapter(intptr_t windowHandle, GraphicsAdapter const& adapter);
GraphicsDeviceManager::GraphicsDeviceManager(sptr<Game> const& game) : game(game)
{
sptr<GraphicsAdapter> adp = GraphicsAdapter::DefaultAdapter();
_information.Adapter = adp;
_information.Profile = xna::GraphicsProfile::HiDef;
information.Adapter = adp;
information.Profile = xna::GraphicsProfile::HiDef;
auto parameters = snew<PresentationParameters>();
parameters->BackBufferWidth = _backBufferWidth;
parameters->BackBufferHeight = _backBufferHeight;
parameters->BackBufferWidth = backBufferWidth;
parameters->BackBufferHeight = backBufferHeight;
parameters->BackBufferFormat = SurfaceFormat::Color;
parameters->Fullscreen = false;
_information.Parameters = parameters;
if (_game)
_information.Window = _game->Window();
}
bool GraphicsDeviceManager::Initialize() {
if (!_game)
return false;
return CreateDevice();
}
parameters->IsFullscreen = false;
information.PresentParameters = parameters;
information.Window = game->Window();
}
void GraphicsDeviceManager::ApplyChanges() {
if (device && !isDeviceDirty)
return;
ChangeDevice(false);
}
bool GraphicsDeviceManager::ToggleFullScreen() {
if (!_game || !_game->graphicsDevice || !_game->graphicsDevice->impl->_swapChain)
if (!game || !game->graphicsDevice || !game->graphicsDevice->impl->_swapChain)
return false;
auto& swap = _game->graphicsDevice->impl->_swapChain;
auto& swap = game->graphicsDevice->impl->_swapChain;
BOOL state = false;
auto hr = swap->impl->dxSwapChain->GetFullscreenState(&state, nullptr);
@ -46,73 +40,351 @@ namespace xna {
if (FAILED(hr)) return false;
_isFullScreen = !state;
isFullScreen = !state;
return true;
}
}
void GraphicsDeviceManager::PreferredBackBufferWidth(Int value) {
_backBufferWidth = value;
_isDeviceDirty = true;
}
void GraphicsDeviceManager::ChangeDevice(bool forceCreate) {
if (!game)
Exception::Throw(Exception::INVALID_OPERATION);
void GraphicsDeviceManager::PreferredBackBufferHeight(Int value) {
_backBufferHeight = value;
_isDeviceDirty = true;
}
bool initWindow(GraphicsDeviceInformation& info, Game& game, int backWidth, int backHeight)
{
auto window = info.Window;
inDeviceTransition = true;
auto screenDeviceName = game->Window()->ScreenDeviceName();
int clientWidth = game->Window()->ClientBounds().Width;
int clientHeight = game->Window()->ClientBounds().Height;
bool flag1 = false;
if (!window) {
window = game.Window();
info.Window = window;
//this.game.Window.SetSupportedOrientations(Helpers.ChooseOrientation(this.supportedOrientations, this.PreferredBackBufferWidth, this.PreferredBackBufferHeight, true));
auto bestDevice = FindBestDevice(forceCreate);
//this.game.Window.BeginScreenDeviceChange(bestDevice.PresentationParameters.IsFullScreen);
flag1 = true;
bool flag2 = true;
if (!forceCreate && device) {
//this.OnPreparingDeviceSettings((object) this, new PreparingDeviceSettingsEventArgs(bestDevice));
if (CanResetDevice(*bestDevice)) {
auto deviceInformation = snew<GraphicsDeviceInformation>(*bestDevice);
MassagePresentParameters(*bestDevice->PresentParameters);
ValidateGraphicsDeviceInformation(*bestDevice);
device->Reset(deviceInformation->PresentParameters, deviceInformation->Adapter);
//GraphicsDeviceManager.ConfigureTouchInput(deviceInformation.PresentationParameters);
flag2 = false;
}
}
window->impl->Size(backWidth, backHeight);
if (flag2)
CreateDevice(*bestDevice);
if (!window->impl->Create()) {
MessageBox(nullptr, "Falha na criação da janela", "XN65", MB_OK);
return false;
}
auto presentationParameters = device->PresentParameters();
info.Parameters->DeviceWindowHandle = reinterpret_cast<intptr_t>(window->impl->WindowHandle());
screenDeviceName = device->Adapter()->DeviceName();
return true;
}
isReallyFullScreen = presentationParameters.IsFullscreen;
bool initDevice(GraphicsDeviceInformation& info, Game& game, sptr<GraphicsDevice>& device)
{
device = snew<GraphicsDevice>(info);
if (presentationParameters.BackBufferWidth != 0)
clientWidth = presentationParameters.BackBufferWidth;
if (!device->Initialize()) {
MessageBox(info.Window->impl->WindowHandle(), "Falha na inicialização do dispositivo gráfico", "XN65", MB_OK);
device = nullptr;
return false;
}
if (presentationParameters.BackBufferHeight != 0)
clientHeight = presentationParameters.BackBufferHeight;
game.graphicsDevice = device;
isDeviceDirty = false;
return true;
}
//if (flag1) game->Window()->EndScreenDeviceChange(screenDeviceName, clientWidth, clientHeight);
bool GraphicsDeviceManager::CreateDevice() {
if (_isDeviceDirty) {
_information.Parameters->BackBufferWidth = _backBufferWidth;
_information.Parameters->BackBufferHeight = _backBufferHeight;
}
auto result = initWindow(_information, *_game, _backBufferWidth, _backBufferHeight);
if (!result) return false;
currentWindowOrientation = game->Window()->CurrentOrientation();
return initDevice(_information, *_game, _device);
inDeviceTransition = false;
}
void GraphicsDeviceManager::ChangeDevice() {
void GraphicsDeviceManager::CreateDevice(GraphicsDeviceInformation& newInfo) {
if (device) {
device = nullptr;
}
//this.OnPreparingDeviceSettings((object)this, new PreparingDeviceSettingsEventArgs(newInfo));
MassagePresentParameters(*newInfo.PresentParameters);
ValidateGraphicsDeviceInformation(newInfo);
const auto windowBounds = game->Window()->ClientBounds();
if (windowBounds.Width != newInfo.PresentParameters->BackBufferWidth || windowBounds.Height != newInfo.PresentParameters->BackBufferHeight) {
game->Window()->impl->Size(
newInfo.PresentParameters->BackBufferWidth,
newInfo.PresentParameters->BackBufferHeight);
game->Window()->impl->Update();
}
device = snew<GraphicsDevice>(newInfo.Adapter, newInfo.Profile, newInfo.PresentParameters);
device->Initialize();
game->graphicsDevice = this->device;
//device.DeviceResetting += new EventHandler<EventArgs>(this.HandleDeviceResetting);
//device.DeviceReset += new EventHandler<EventArgs>(this.HandleDeviceReset);
//device.DeviceLost += new EventHandler<EventArgs>(this.HandleDeviceLost);
//device.Disposing += new EventHandler<EventArgs>(this.HandleDisposing);
//GraphicsDeviceManager.ConfigureTouchInput(newInfo.PresentationParameters);
//this.OnDeviceCreated((object)this, EventArgs.Empty);*/
}
void GraphicsDeviceManager::AddDevices(bool anySuitableDevice, std::vector<sptr<GraphicsDeviceInformation>>& foundDevices) {
const auto handle = game->Window()->Handle();
std::vector<uptr<GraphicsAdapter>> adapters;
GraphicsAdapter::Adapters(adapters);
for (size_t i = 0; i < adapters.size(); ++i) {
auto& adapter = adapters[i];
if (!anySuitableDevice) {
if (!IsWindowOnAdapter(handle, *adapter))
continue;
}
if (adapter->IsProfileSupported(graphicsProfile)) {
auto baseDeviceInfo = snew<GraphicsDeviceInformation>();
baseDeviceInfo->Adapter = std::move(adapter);
baseDeviceInfo->Profile = graphicsProfile;
baseDeviceInfo->PresentParameters = snew<PresentationParameters>();
baseDeviceInfo->PresentParameters->DeviceWindowHandle = handle;
baseDeviceInfo->PresentParameters->MultiSampleCount = 0;
baseDeviceInfo->PresentParameters->IsFullscreen = isFullScreen;
baseDeviceInfo->PresentParameters->PresentationInterval = synchronizeWithVerticalRetrace ? PresentInterval::One : PresentInterval::Immediate;
const auto& currentDisplayMode = baseDeviceInfo->Adapter->CurrentDisplayMode();
AddDevices(*baseDeviceInfo->Adapter, *currentDisplayMode, baseDeviceInfo, foundDevices);
if (isFullScreen) {
const auto& supportedDisplayModes = adapter->SupportedDisplayModes();
const auto count = supportedDisplayModes->Count();
for (size_t i = 0; i < count; ++i) {
auto& supportedDisplayMode = supportedDisplayModes->DisplayModes[i];
if (supportedDisplayMode->Width() >= 640 && supportedDisplayMode->Height() >= 480) {
AddDevices(*baseDeviceInfo->Adapter, *supportedDisplayMode, baseDeviceInfo, foundDevices);
}
}
}
}
}
}
void GraphicsDeviceManager::AddDevices(GraphicsAdapter const& adapter, DisplayMode const& mode, sptr<GraphicsDeviceInformation>& baseDeviceInfo, std::vector<sptr<GraphicsDeviceInformation>>& foundDevices) const {
auto deviceInformation = snew<GraphicsDeviceInformation>(*baseDeviceInfo);
if (isFullScreen)
{
deviceInformation->PresentParameters->BackBufferWidth = mode.Width();
deviceInformation->PresentParameters->BackBufferHeight = mode.Height();
}
else if (useResizedBackBuffer) {
deviceInformation->PresentParameters->BackBufferWidth = resizedBackBufferWidth;
deviceInformation->PresentParameters->BackBufferHeight = resizedBackBufferHeight;
}
else {
deviceInformation->PresentParameters->BackBufferWidth = backBufferWidth;
deviceInformation->PresentParameters->BackBufferHeight = backBufferHeight;
}
SurfaceFormat selectedFormat;
DepthFormat selectedDepthFormat;
int selectedMultiSampleCount;
adapter.QueryBackBufferFormat(deviceInformation->Profile, mode.Format(), depthStencilFormat, allowMultiSampling ? 16 : 0, selectedFormat, selectedDepthFormat, selectedMultiSampleCount);
deviceInformation->PresentParameters->BackBufferFormat = selectedFormat;
deviceInformation->PresentParameters->DepthStencilFormat = selectedDepthFormat;
deviceInformation->PresentParameters->MultiSampleCount = selectedMultiSampleCount;
if (std::find(foundDevices.begin(), foundDevices.end(), deviceInformation) != foundDevices.end())
return;
foundDevices.push_back(deviceInformation);
}
sptr<GraphicsDeviceInformation> GraphicsDeviceManager::FindBestPlatformDevice(bool anySuitableDevice) {
auto foundDevices = std::vector<sptr<GraphicsDeviceInformation>>();
AddDevices(anySuitableDevice, foundDevices);
if (foundDevices.size() == 0 && allowMultiSampling) {
PreferMultiSampling(false);
AddDevices(anySuitableDevice, foundDevices);
}
if (foundDevices.size() == 0) {
Exception::Throw("No Suitable Graphics Device");
}
RankDevices(foundDevices);
if (foundDevices.size() == 0)
Exception::Throw("No Suitable Graphics Device");
return foundDevices[0];
}
struct GraphicsDeviceInformationComparer
{
GraphicsDeviceManager* graphics = nullptr;
bool operator()(GraphicsDeviceInformation const& d1, GraphicsDeviceInformation const& d2) const {
return comparator(d1, d2);
}
bool operator()(sptr<GraphicsDeviceInformation> const& a, sptr<GraphicsDeviceInformation> const& b) const {
return comparator(*a, *b);
}
private:
bool comparator(GraphicsDeviceInformation const& d1, GraphicsDeviceInformation const& d2) const {
if (d1.Profile != d2.Profile)
return d1.Profile <= d2.Profile;
auto& presentationParameters1 = d1.PresentParameters;
auto& presentationParameters2 = d2.PresentParameters;
if (presentationParameters1 && presentationParameters2 && presentationParameters1->IsFullscreen != presentationParameters2->IsFullscreen)
return graphics->IsFullScreen() != presentationParameters1->IsFullscreen;
const auto& backFormat1 = presentationParameters1->BackBufferFormat;
const auto& backFormat2 = presentationParameters2->BackBufferFormat;
if (backFormat1 != backFormat2)
return static_cast<int>(backFormat1) <= static_cast<int>(backFormat2);
if (presentationParameters1->MultiSampleCount != presentationParameters2->MultiSampleCount)
return presentationParameters1->MultiSampleCount <= presentationParameters2->MultiSampleCount;
const auto num3 = graphics->PreferredBackBufferWidth() == 0 || graphics->PreferredBackBufferHeight() == 0
? GraphicsDeviceManager::DefaultBackBufferWidth / static_cast<float>(GraphicsDeviceManager::DefaultBackBufferHeight)
: graphics->PreferredBackBufferWidth() / static_cast<float>(graphics->PreferredBackBufferHeight());
const auto num4 = presentationParameters1->BackBufferWidth / static_cast<float>(presentationParameters1->BackBufferHeight);
const auto num5 = presentationParameters2->BackBufferWidth / static_cast<float>(presentationParameters2->BackBufferHeight);
const auto num6 = std::abs(num4 - num3);
const auto num7 = std::abs(num5 - num3);
if (std::abs(num6 - num7) > 0.20000000298023224)
return num6 <= num7;
Int num8;
Int num9;
if (graphics->IsFullScreen())
{
if (graphics->PreferredBackBufferWidth() == 0 || graphics->PreferredBackBufferHeight() == 0) {
const auto& adapter1 = d1.Adapter;
num8 = adapter1->CurrentDisplayMode()->Width() * adapter1->CurrentDisplayMode()->Height();
const auto& adapter2 = d2.Adapter;
num9 = adapter2->CurrentDisplayMode()->Width() * adapter2->CurrentDisplayMode()->Height();
}
else
num8 = num9 = graphics->PreferredBackBufferWidth() * graphics->PreferredBackBufferHeight();
}
else
num8 = graphics->PreferredBackBufferWidth() == 0 || graphics->PreferredBackBufferHeight() == 0
? (num9 = GraphicsDeviceManager::DefaultBackBufferWidth * GraphicsDeviceManager::DefaultBackBufferHeight)
: (num9 = graphics->PreferredBackBufferWidth() * graphics->PreferredBackBufferHeight());
const auto num10 = std::abs(presentationParameters1->BackBufferWidth * presentationParameters1->BackBufferHeight - num8);
const auto num11 = std::abs(presentationParameters2->BackBufferWidth * presentationParameters2->BackBufferHeight - num9);
if (num10 != num11)
return num10 <= num11;
if (d1.Adapter != d2.Adapter) {
if (d1.Adapter->IsDefaultAdapter())
return false;
if (d2.Adapter->IsDefaultAdapter())
return true;
}
return false;
}
};
void GraphicsDeviceManager::RankDevicesPlatform(std::vector<sptr<GraphicsDeviceInformation>>& foundDevices) {
GraphicsDeviceInformationComparer comparer;
comparer.graphics = this;
std::sort(foundDevices.begin(), foundDevices.end(), comparer);
}
bool GraphicsDeviceManager::CanResetDevice(GraphicsDeviceInformation& newDeviceInfo) {
return device->Profile() == newDeviceInfo.Profile;
}
void GraphicsDeviceManager::MassagePresentParameters(PresentationParameters& pp) {
const auto flag1 = pp.BackBufferWidth == 0;
const auto flag2 = pp.BackBufferHeight == 0;
if (pp.IsFullscreen)
return;
auto hWnd = pp.DeviceWindowHandle;
if (hWnd == 0) {
if (!game)
Exception::Throw(Exception::INVALID_OPERATION);
hWnd = game->Window()->Handle();
}
/*NativeMethods.RECT rect;
NativeMethods.GetClientRect(hWnd, out rect);
if (flag1 && rect.Right == 0)
pp.BackBufferWidth = 1;
if (!flag2 || rect.Bottom != 0)
return;
pp.BackBufferHeight = 1;*/
}
void GraphicsDeviceManager::ValidateGraphicsDeviceInformation(GraphicsDeviceInformation& devInfo) {
const auto& adapter = devInfo.Adapter;
auto& presentationParameters = devInfo.PresentParameters;
if (!presentationParameters->IsFullscreen)
return;
if (presentationParameters->BackBufferWidth == 0 || presentationParameters->BackBufferHeight == 0)
Exception::Throw(Exception::INVALID_OPERATION);
bool flag = true;
const auto& currentDisplayMode = adapter->CurrentDisplayMode();
if (currentDisplayMode->Format() != presentationParameters->BackBufferFormat && currentDisplayMode->Width() != presentationParameters->BackBufferWidth
&& currentDisplayMode->Height() != presentationParameters->BackBufferHeight)
{
flag = false;
const auto& supportedDisplayModes = adapter->SupportedDisplayModes();
const size_t count = supportedDisplayModes->Count();
for (size_t i = 0; i < count; ++i) {
const auto& displayMode = supportedDisplayModes->DisplayModes[i];
if (displayMode->Width() == presentationParameters->BackBufferWidth && displayMode->Height() == presentationParameters->BackBufferHeight) {
flag = true;
break;
}
}
}
if (!flag)
Exception::Throw(Exception::INVALID_OPERATION);
}
bool IsWindowOnAdapter(intptr_t windowHandle, GraphicsAdapter const& adapter) {
const auto fromAdapter = GameWindow::ScreenFromAdapter(adapter);
const auto fromHandle = GameWindow::ScreenFromHandle(windowHandle);
return (fromAdapter && fromHandle) && (*fromAdapter == *fromHandle);
}
}

View File

@ -68,11 +68,11 @@ namespace xna {
}
float RasterizerState::DepthBias() const {
return impl->dxDescription.DepthBias;
return static_cast<float>(impl->dxDescription.DepthBias);
}
void RasterizerState::DepthBias(float value) {
impl->dxDescription.DepthBias = value;
impl->dxDescription.DepthBias = static_cast<INT>(value);
}
float RasterizerState::SlopeScaleDepthBias() const {

View File

@ -65,7 +65,10 @@ namespace xna {
states[i]->AddRef();
}
device.impl->_context->PSSetSamplers(0, states.size(), states.data());
device.impl->_context->PSSetSamplers(
0,
static_cast<UINT>(states.size()),
states.data());
for (size_t i = 0; i < samplers.size(); ++i) {
states[i]->Release();

View File

@ -0,0 +1,59 @@
#include "xna/xna-dx.hpp"
namespace xna {
//See ref
//
//https://learn.microsoft.com/pt-br/windows/win32/api/winuser/nf-winuser-getmonitorinfoa
//https://learn.microsoft.com/pt-br/windows/win32/api/winuser/ns-winuser-monitorinfoexa
//https://stackoverflow.com/questions/7767036/how-do-i-get-the-number-of-displays-in-windows
//
static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
auto screens = (std::vector<uptr<Screen>>*)dwData;
MONITORINFOEX monitorInfo{};
monitorInfo.cbSize = sizeof(MONITORINFOEX);
GetMonitorInfo(hMonitor, &monitorInfo);
const auto hmonitor = reinterpret_cast<intptr_t>(hMonitor);
const auto primary = monitorInfo.dwFlags == MONITORINFOF_PRIMARY;
Rectangle bounds;
bounds.X = monitorInfo.rcMonitor.left;
bounds.Y = monitorInfo.rcMonitor.top;
bounds.Width = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left;
bounds.Height = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top;
Rectangle workingArea;
workingArea.X = monitorInfo.rcWork.left;
workingArea.Y = monitorInfo.rcWork.top;
workingArea.Width = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
workingArea.Height = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
const auto deviceName = String(monitorInfo.szDevice);
auto screen = unew<Screen>(
hmonitor,
primary,
bounds,
workingArea,
deviceName
);
screens->push_back(std::move(screen));
return TRUE;
}
std::vector<uptr<Screen>> Screen::AllScreens() {
std::vector<uptr<Screen>> screens;
if (EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&screens))
return screens;
return std::vector<uptr<Screen>>();
}
}

View File

@ -1,11 +1,3 @@
#include "xna/graphics/rasterizerstate.hpp"
#include "xna/graphics/samplerstate.hpp"
#include "xna/common/color.hpp"
#include "xna/common/numerics.hpp"
#include "xna/graphics/sprite.hpp"
#include "xna/graphics/viewport.hpp"
#include "xna/graphics/blendstate.hpp"
#include "xna/graphics/depthstencilstate.hpp"
#include "xna/xna-dx.hpp"
#include <functional>
@ -31,11 +23,11 @@ namespace xna {
std::vector<Vector3> const& kerning,
std::optional<Char> const& defaultCharacter)
{
if (!texture || !texture->impl->dxShaderResource)
throw std::invalid_argument("SpriteFont: texture is null.");
Exception::ThrowIfNull(texture, nameof(texture));
Exception::ThrowIfNull(texture->impl->dxShaderResource.Get(), nameof(texture->impl->dxShaderResource));
if(cropping.size() != glyphs.size() || charMap.size() != glyphs.size() || (!kerning.empty() && kerning.size() != glyphs.size()))
throw std::invalid_argument("SpriteFont: cropping, charmap and kerning (if not empty) must all be the same size.");
Exception::Throw("Cropping, charmap and kerning (if not empty) must all be the same size.");
std::vector<DxGlyph> dxGlyps(glyphs.size());
@ -62,7 +54,7 @@ namespace xna {
}
impl = unew<PlatformImplementation>();
impl->_dxSpriteFont = unew<DxSpriteFont>(
impl->dxSpriteFont = unew<DxSpriteFont>(
//ID3D11ShaderResourceView* texture
texture->impl->dxShaderResource.Get(),
//Glyph const* glyphs
@ -75,16 +67,12 @@ namespace xna {
if (defaultCharacter.has_value()) {
const auto defChar = static_cast<wchar_t>(defaultCharacter.value());
impl->_dxSpriteFont->SetDefaultCharacter(defChar);
impl->dxSpriteFont->SetDefaultCharacter(defChar);
}
}
Vector2 SpriteFont::MeasureString(String const& text, bool ignoreWhiteSpace)
{
if (!impl->_dxSpriteFont)
return Vector2();
const auto size = impl->_dxSpriteFont->MeasureString(text.c_str(), ignoreWhiteSpace);
Vector2 SpriteFont::MeasureString(String const& text, bool ignoreWhiteSpace) {
const auto size = impl->dxSpriteFont->MeasureString(text.c_str(), ignoreWhiteSpace);
Vector2 vec2{};
vec2.X = size.m128_f32[0];
vec2.Y = size.m128_f32[1];
@ -92,12 +80,8 @@ namespace xna {
return vec2;
}
Vector2 SpriteFont::MeasureString(WString const& text, bool ignoreWhiteSpace)
{
if (!impl->_dxSpriteFont)
return Vector2();
const auto size = impl->_dxSpriteFont->MeasureString(text.c_str(), ignoreWhiteSpace);
Vector2 SpriteFont::MeasureString(WString const& text, bool ignoreWhiteSpace){
const auto size = impl->dxSpriteFont->MeasureString(text.c_str(), ignoreWhiteSpace);
Vector2 vec2{};
vec2.X = size.m128_f32[0];
vec2.Y = size.m128_f32[1];
@ -106,30 +90,30 @@ namespace xna {
}
Char SpriteFont::DefaultCharacter() const {
const auto defChar = impl->_dxSpriteFont->GetDefaultCharacter();
const auto defChar = impl->dxSpriteFont->GetDefaultCharacter();
return static_cast<Char>(defChar);
}
void SpriteFont::DefaultCharacter(Char value) {
const auto defChar = static_cast<wchar_t>(value);
impl->_dxSpriteFont->SetDefaultCharacter(defChar);
impl->dxSpriteFont->SetDefaultCharacter(defChar);
}
Int SpriteFont::LineSpacing() const {
const auto space = impl->_dxSpriteFont->GetLineSpacing();
const auto space = impl->dxSpriteFont->GetLineSpacing();
return static_cast<Int>(space);
}
void SpriteFont::LineSpacing(Int value) {
impl->_dxSpriteFont->SetLineSpacing(static_cast<float>(value));
void SpriteFont::LineSpacing(float value) {
impl->dxSpriteFont->SetLineSpacing(value);
}
SpriteBatch::SpriteBatch(sptr<GraphicsDevice> const& device) : GraphicsResource(device) {
if (!device->impl->_context)
return;
Exception::ThrowIfNull(device, nameof(device));
Exception::ThrowIfNull(device->impl->_context.Get(), nameof(device->impl->_context));
impl = unew<PlatformImplementation>();
impl->_dxspriteBatch = snew<DxSpriteBatch>(
impl->dxSpriteBatch = snew<DxSpriteBatch>(
//ID3D11DeviceContext* deviceContext
device->impl->_context.Get()
);
@ -138,31 +122,18 @@ namespace xna {
}
void SpriteBatch::Begin(SpriteSortMode sortMode, BlendState* blendState, SamplerState* samplerState, DepthStencilState* depthStencil, RasterizerState* rasterizerState, Effect* effect, Matrix const& transformMatrix) {
if (!impl->_dxspriteBatch)
return;
DxSpriteSortMode sort = DxHelpers::SpriteSortToDx(sortMode);
const auto& t = transformMatrix;
DxMatrix matrix = DxMatrix(
t.M11, t.M12, t.M13, t.M14,
t.M21, t.M22, t.M23, t.M24,
t.M31, t.M32, t.M33, t.M34,
t.M41, t.M42, t.M43, t.M44);
std::function<void __cdecl()> effectFunc = nullptr;
//if Effect is not null set effectBuffer and inputLayout
if (effect && effect->impl) {
bool effectBufferChanged = false;
//if Effect is not null set dxEffectBuffer and inputLayout
if (effect) {
bool dxEffectBufferChanged = false;
if (!impl->effectBuffer || impl->effectBuffer != effect->impl->dxEffect) {
impl->effectBuffer = effect->impl->dxEffect;
effectBufferChanged = true;
if (!impl->dxEffectBuffer || impl->dxEffectBuffer != effect->impl->dxEffect) {
impl->dxEffectBuffer = effect->impl->dxEffect;
dxEffectBufferChanged = true;
}
if (effectBufferChanged) {
if (!impl->dxInputLayout || dxEffectBufferChanged) {
void const* shaderByteCode;
size_t byteCodeLength;
@ -178,68 +149,53 @@ namespace xna {
auto& context = m_device->impl->_context;
effectFunc = [=] {
impl->effectBuffer->Apply(context.Get());
impl->dxEffectBuffer->Apply(context.Get());
context->IASetInputLayout(impl->dxInputLayout.Get());
};
}
impl->_dxspriteBatch->Begin(
sort,
auto _sortMode = DxHelpers::SpriteSortToDx(sortMode);
auto _transformMatrix = DxHelpers::MatrixToDx(transformMatrix);
impl->dxSpriteBatch->Begin(
_sortMode,
blendState ? blendState->impl->dxBlendState.Get() : nullptr,
samplerState ? samplerState->impl->_samplerState.Get() : nullptr,
depthStencil ? depthStencil->impl->dxDepthStencil.Get() : nullptr,
rasterizerState ? rasterizerState->impl->dxRasterizerState.Get() : nullptr,
effectFunc,
matrix
_transformMatrix
);
}
void SpriteBatch::End() {
if (!impl->_dxspriteBatch)
return;
impl->_dxspriteBatch->End();
impl->dxSpriteBatch->End();
}
void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, Color const& color) {
if (!impl->_dxspriteBatch)
return;
if (!texture.impl->dxShaderResource)
return;
const auto _position = XMFLOAT2(position.X, position.Y);
const auto _position = DxHelpers::VectorToDx(position);
const auto v4 = color.ToVector4();
XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
const auto _color = DxHelpers::VectorToDx(v4);
impl->_dxspriteBatch->Draw(
impl->dxSpriteBatch->Draw(
texture.impl->dxShaderResource.Get(),
_position,
_color
);
}
void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, std::optional<Rectangle> const& sourceRectangle, Color const& color) {
if (!impl->_dxspriteBatch)
return;
if (!texture.impl->dxShaderResource)
return;
const auto _position = XMFLOAT2(position.X, position.Y);
void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, std::optional<Rectangle> const& sourceRectangle, Color const& color) {
const auto _position = DxHelpers::VectorToDx(position);
const auto v4 = color.ToVector4();
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
const auto _color = DxHelpers::VectorToDx(v4);
RECT _sourceRect{};
if (sourceRectangle.has_value()) {
_sourceRect.top = sourceRectangle->Y;
_sourceRect.left = sourceRectangle->X;
_sourceRect.right = sourceRectangle->X + sourceRectangle->Width;
_sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height;
_sourceRect = DxHelpers::RectangleToDx(sourceRectangle.value());
};
impl->_dxspriteBatch->Draw(
impl->dxSpriteBatch->Draw(
texture.impl->dxShaderResource.Get(),
_position,
sourceRectangle ? &_sourceRect : nullptr,
@ -247,29 +203,20 @@ namespace xna {
}
void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, std::optional<Rectangle> const& sourceRectangle, Color const& color, float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth) {
if (!impl->_dxspriteBatch)
return;
if (!texture.impl->dxShaderResource)
return;
const auto _position = XMFLOAT2(position.X, position.Y);
const auto _origin = XMFLOAT2(origin.X, origin.Y);
const auto _position = DxHelpers::VectorToDx(position);
const auto _origin = DxHelpers::VectorToDx(origin);
const auto v4 = color.ToVector4();
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
const auto _color = DxHelpers::VectorToDx(v4);
RECT _sourceRect{};
if (sourceRectangle.has_value()) {
_sourceRect.top = sourceRectangle->Y;
_sourceRect.left = sourceRectangle->X;
_sourceRect.right = sourceRectangle->X + sourceRectangle->Width;
_sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height;
_sourceRect = DxHelpers::RectangleToDx(sourceRectangle.value());
};
const DxSpriteEffects _effects = static_cast<DxSpriteEffects>(effects);
impl->_dxspriteBatch->Draw(
impl->dxSpriteBatch->Draw(
texture.impl->dxShaderResource.Get(),
_position,
sourceRectangle ? &_sourceRect : nullptr,
@ -282,12 +229,6 @@ namespace xna {
}
void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, std::optional<Rectangle> const& sourceRectangle, Color const& color, float rotation, Vector2 const& origin, Vector2 const& scale, SpriteEffects effects, float layerDepth) {
if (!impl->_dxspriteBatch)
return;
if (!texture.impl->dxShaderResource)
return;
const auto _position = XMFLOAT2(position.X, position.Y);
const auto _origin = XMFLOAT2(origin.X, origin.Y);
const auto v4 = color.ToVector4();
@ -296,16 +237,13 @@ namespace xna {
RECT _sourceRect{};
if (sourceRectangle.has_value()) {
_sourceRect.top = sourceRectangle->Y;
_sourceRect.left = sourceRectangle->X;
_sourceRect.right = sourceRectangle->X + sourceRectangle->Width;
_sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height;
_sourceRect = DxHelpers::RectangleToDx(sourceRectangle.value());
};
const auto _effects = static_cast<DxSpriteEffects>(effects);
const XMFLOAT2 _scale = { scale.X, scale.Y };
impl->_dxspriteBatch->Draw(
impl->dxSpriteBatch->Draw(
texture.impl->dxShaderResource.Get(),
_position,
sourceRectangle ? &_sourceRect : nullptr,
@ -318,36 +256,16 @@ namespace xna {
}
void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, Color const& color) {
if (!impl->_dxspriteBatch)
return;
if (!texture.impl->dxShaderResource)
return;
RECT _destinationRect{};
_destinationRect.left = destinationRectangle.X;
_destinationRect.top = destinationRectangle.Y;
_destinationRect.right = destinationRectangle.X + destinationRectangle.Width;
_destinationRect.bottom = destinationRectangle.Y + destinationRectangle.Height;
RECT _destinationRect = DxHelpers::RectangleToDx(destinationRectangle);
const auto v4 = color.ToVector4();
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
impl->_dxspriteBatch->Draw(texture.impl->dxShaderResource.Get(), _destinationRect, _color);
impl->dxSpriteBatch->Draw(texture.impl->dxShaderResource.Get(), _destinationRect, _color);
}
void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, std::optional<Rectangle> const& sourceRectangle, Color const& color) {
if (!impl->_dxspriteBatch)
return;
if (!texture.impl->dxShaderResource)
return;
RECT _destinationRect{};
_destinationRect.left = destinationRectangle.X;
_destinationRect.top = destinationRectangle.Y;
_destinationRect.right = destinationRectangle.X + destinationRectangle.Width;
_destinationRect.bottom = destinationRectangle.Y + destinationRectangle.Height;
RECT _destinationRect = DxHelpers::RectangleToDx(destinationRectangle);
const auto v4 = color.ToVector4();
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
@ -361,21 +279,11 @@ namespace xna {
_sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height;
};
impl->_dxspriteBatch->Draw(texture.impl->dxShaderResource.Get(), _destinationRect, sourceRectangle ? &_sourceRect : nullptr, _color);
impl->dxSpriteBatch->Draw(texture.impl->dxShaderResource.Get(), _destinationRect, sourceRectangle ? &_sourceRect : nullptr, _color);
}
void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, std::optional<Rectangle> const& sourceRectangle, Color const& color, float rotation, Vector2 const& origin, SpriteEffects effects, float layerDepth) {
if (!impl->_dxspriteBatch)
return;
if (!texture.impl->dxShaderResource)
return;
RECT _destinationRect{};
_destinationRect.left = destinationRectangle.X;
_destinationRect.top = destinationRectangle.Y;
_destinationRect.right = destinationRectangle.X + destinationRectangle.Width;
_destinationRect.bottom = destinationRectangle.Y + destinationRectangle.Height;
RECT _destinationRect = DxHelpers::RectangleToDx(destinationRectangle);
const auto v4 = color.ToVector4();
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
@ -383,16 +291,13 @@ namespace xna {
RECT _sourceRect{};
if (sourceRectangle.has_value()) {
_sourceRect.top = sourceRectangle->Y;
_sourceRect.left = sourceRectangle->X;
_sourceRect.right = sourceRectangle->X + sourceRectangle->Width;
_sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height;
_sourceRect = DxHelpers::RectangleToDx(sourceRectangle.value());
};
auto _origin = XMFLOAT2(origin.X, origin.Y);
const auto _effects = static_cast<DxSpriteEffects>(effects);
impl->_dxspriteBatch->Draw(
impl->dxSpriteBatch->Draw(
texture.impl->dxShaderResource.Get(),
_destinationRect,
sourceRectangle ? &_sourceRect : nullptr,
@ -404,30 +309,17 @@ namespace xna {
}
void SpriteBatch::Viewport(xna::Viewport const& value) {
if (!impl->_dxspriteBatch)
return;
D3D11_VIEWPORT _view{};
_view.TopLeftX = value.X;
_view.TopLeftY = value.Y;
_view.Width = value.Width;
_view.Height = value.Height;
_view.MinDepth = value.MinDetph;
_view.MaxDepth = value.MaxDepth;
impl->_dxspriteBatch->SetViewport(_view);
const auto _view = DxHelpers::ViewportToDx(value);
impl->dxSpriteBatch->SetViewport(_view);
}
void SpriteBatch::DrawString(SpriteFont& spriteFont, String const& text, Vector2 const& position, Color const& color) {
if (!impl->_dxspriteBatch || !spriteFont.impl->_dxSpriteFont)
return;
const auto _position = XMFLOAT2(position.X, position.Y);
const auto v4 = color.ToVector4();
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
spriteFont.impl->_dxSpriteFont->DrawString(
impl->_dxspriteBatch.get(),
spriteFont.impl->dxSpriteFont->DrawString(
impl->dxSpriteBatch.get(),
text.c_str(),
_position,
_color
@ -436,17 +328,14 @@ namespace xna {
void SpriteBatch::DrawString(SpriteFont& spriteFont, String const& text, Vector2 const& position,
Color const& color, float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth) {
if (!impl->_dxspriteBatch || !spriteFont.impl->_dxSpriteFont)
return;
const auto _position = XMFLOAT2(position.X, position.Y);
const auto _origin = XMFLOAT2(origin.X, origin.Y);
const auto v4 = color.ToVector4();
const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W };
const auto _effects = static_cast<DxSpriteEffects>(effects);
spriteFont.impl->_dxSpriteFont->DrawString(
impl->_dxspriteBatch.get(),
spriteFont.impl->dxSpriteFont->DrawString(
impl->dxSpriteBatch.get(),
text.c_str(),
_position,
_color,

View File

@ -24,18 +24,13 @@ namespace xna {
swapChain.ReleaseAndGetAddressOf();
}
auto adapter = device.Adapter();
auto dxAdapter = adapter->impl->dxadapter;
auto adapter = device.Adapter();
IDXGIFactory1* dxFactory1 = nullptr;
auto hr = dxAdapter->GetParent(IID_IDXGIFactory1, (void**)&dxFactory1);
comptr<IDXGIFactory2> dxFactory2 = nullptr;
const auto hr = adapter->impl->dxFactory->QueryInterface(IID_IDXGIFactory2, (void**)&dxFactory2);
if (FAILED(hr)) return false;
IDXGIFactory2* dxFactory2 = nullptr;
hr = dxFactory1->QueryInterface(IID_IDXGIFactory2, (void**)&dxFactory2);
if (FAILED(hr)) return false;
if (FAILED(hr))
return false;
dxFactory2->CreateSwapChainForHwnd(
device.impl->_device.Get(),
@ -45,7 +40,6 @@ namespace xna {
nullptr,
swapChain.GetAddressOf());
return true;
}
@ -70,7 +64,7 @@ namespace xna {
impl->dxFullScreenDescription.RefreshRate.Denominator = 1;
impl->dxFullScreenDescription.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
impl->dxFullScreenDescription.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
impl->dxFullScreenDescription.Windowed = !parameters->Fullscreen;
impl->dxFullScreenDescription.Windowed = !parameters->IsFullscreen;
HWND hwnd = reinterpret_cast<HWND>(parameters->DeviceWindowHandle);
return internalInit(*m_device, hwnd, impl->dxSwapChain, impl->dxDescription, impl->dxFullScreenDescription);

View File

@ -2,20 +2,17 @@
namespace xna {
GameWindow::GameWindow() {
impl = unew<PlatformImplementation>();
impl = unew<PlatformImplementation>(this);
impl->_hInstance = GetModuleHandle(NULL);
impl->_windowIcon = LoadIcon(NULL, IDI_APPLICATION);
impl->_windowCursor = LoadCursor(NULL, IDC_ARROW);
impl->_windowStyle = static_cast<int>(GameWindowMode::Windowed);
impl->_windowCenterX = impl->_windowWidth / 2.0F;
impl->_windowCenterY = impl->_windowHeight / 2.0F;
}
GameWindow::~GameWindow() {
impl = nullptr;
}
impl->_windowCenterY = impl->_windowHeight / 2.0F;
impl->_windowWidth = GameWindow::DefaultClientWidth;
impl->_windowHeight = GameWindow::DefaultClientHeight;
}
void GameWindow::PlatformImplementation::Position(int width, int height, bool update) {
_windowPosX = width;
@ -34,9 +31,8 @@ namespace xna {
if(update) Update();
}
void GameWindow::Title(String const& title) {
if (!impl) return;
void GameWindow::Title(String const& value) {
title = value;
impl->_windowTitle = title;
}
@ -89,9 +85,35 @@ namespace xna {
winRect.bottom - winRect.top,
TRUE);
return _windowHandle ? true : false;
if (!_windowHandle)
return false;
}
//
// GameWindow
//
const auto handle = reinterpret_cast<intptr_t>(_windowHandle);
gameWindow->handle = handle;
gameWindow->title = _windowTitle;
gameWindow->clientBounds = { _windowPosX, _windowPosY, _windowWidth, _windowHeight };
gameWindow->currentOrientation = DisplayOrientation::Default;
auto screens = Screen::AllScreens();
if (screens.size() == 1)
gameWindow->screenDeviceName = screens[0]->DeviceName();
else {
for (size_t i = 0; i < screens.size(); ++i) {
const auto& screen = screens[i];
if (screen->Primary())
gameWindow->screenDeviceName = screen->DeviceName();
}
}
return true;
}
@ -118,30 +140,13 @@ namespace xna {
return _windowHandle ? true : false;
}
gameWindow->clientBounds = { _windowPosX, _windowPosY, _windowWidth, _windowHeight };
return true;
}
}
String GameWindow::Title() const {
if (!impl) return String();
return impl->_windowTitle;
}
Rectangle GameWindow::ClientBounds() const {
if (!impl) return {};
return Rectangle(
impl->_windowPosX,
impl->_windowPosY,
impl->_windowWidth,
impl->_windowHeight
);
}
intptr_t GameWindow::Handle() const {
if (!impl) return 0;
return reinterpret_cast<intptr_t>(impl->_windowHandle);
bool GameWindow::IsWindowMinimized() const {
return IsIconic(impl->_windowHandle);
}
LRESULT GameWindow::PlatformImplementation::WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
@ -189,4 +194,61 @@ namespace xna {
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
uptr<Screen> GameWindow::ScreenFromAdapter(GraphicsAdapter const& adapter) {
auto screens = Screen::AllScreens();
for (size_t i = 0; i < screens.size(); ++i) {
auto& screen = screens[i];
if (screen->DeviceName() == adapter.DeviceName())
return std::move(screen);
}
return nullptr;
}
uptr<Screen> GameWindow::ScreenFromHandle(intptr_t windowHandle) {
const auto handle = reinterpret_cast<HWND>(windowHandle);
auto hMonitor = MonitorFromWindow(handle, MONITOR_DEFAULTTOPRIMARY);
if (!hMonitor)
return nullptr;
MONITORINFOEX monitorInfo{};
monitorInfo.cbSize = sizeof(MONITORINFOEX);
GetMonitorInfo(hMonitor, &monitorInfo);
const auto hmonitor = reinterpret_cast<intptr_t>(hMonitor);
const auto primary = monitorInfo.dwFlags == MONITORINFOF_PRIMARY;
Rectangle bounds;
bounds.X = monitorInfo.rcMonitor.left;
bounds.Y = monitorInfo.rcMonitor.top;
bounds.Width = monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left;
bounds.Height = monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top;
Rectangle workingArea;
workingArea.X = monitorInfo.rcWork.left;
workingArea.Y = monitorInfo.rcWork.top;
workingArea.Width = monitorInfo.rcWork.right - monitorInfo.rcWork.left;
workingArea.Height = monitorInfo.rcWork.bottom - monitorInfo.rcWork.top;
const auto deviceName = String(monitorInfo.szDevice);
auto screen = unew<Screen>(
hmonitor,
primary,
bounds,
workingArea,
deviceName
);
return screen;
}
String GameWindow::ScreenDeviceName() const {
const auto screen = ScreenFromHandle(handle);
return screen->DeviceName();
}
}

View File

@ -17,11 +17,12 @@ namespace xna {
static constexpr float Min(float value1, float value2) { return (std::min)(value1, value2); }
static constexpr float Max(float value1, float value2) { return (std::max)(value1, value2); }
static constexpr float Clamp(float value, float min, float max) {
template <typename T>
static constexpr T Clamp(T value, T min, T max) {
value = value > max ? max : value;
value = value < min ? min : value;
return value;
}
}
static constexpr float Lerp(float value1, float value2, float amount) {
return value1 + (value2 - value1) * amount;

View File

@ -6,6 +6,23 @@
#include <optional>
namespace xna {
//Represents a rational number.
struct RationalNumber {
constexpr RationalNumber() = default;
constexpr RationalNumber(Uint numerator, Uint denominator)
: Numerator(numerator), Denominator(denominator) {}
constexpr bool operator==(const RationalNumber& other) const {
return Numerator == other.Numerator && Denominator == other.Denominator;
}
//An unsigned integer value representing the top of the rational number.
Uint Numerator{ 0 };
//An unsigned integer value representing the bottom of the rational number.
Uint Denominator{ 0 };
};
struct Point {
Int X{ 0 };
Int Y{ 0 };

View File

@ -176,7 +176,7 @@ namespace xna {
if (typeReader.TargetIsValueType)
return InvokeReader<T>(typeReader, existingInstance);
ReadObjectInternal<T>(existingInstance);
return ReadObjectInternal<T>(existingInstance);
}
}

View File

@ -0,0 +1,44 @@
#ifndef XNA_CSHARP_EVENTHANDLER_HPP
#define XNA_CSHARP_EVENTHANDLER_HPP
#include <functional>
#include <vector>
namespace xna {
struct EventArgs {
virtual ~EventArgs() {
sender = nullptr;
}
void** sender = nullptr;
};
template <typename TEventArgs>
struct EventHandler {
template <typename _Ptr>
using HANDLER_CALLBACK = void(_Ptr::*&)(TEventArgs& args);
template <class _Ptr>
void Add(HANDLER_CALLBACK<_Ptr> function, _Ptr* ptr) {
using std::placeholders::_1;
std::function<void(TEventArgs&)> func = std::bind(function, ptr, _1);
funcs.push_back(func);
}
void operator()(TEventArgs& args) {
for (size_t i = 0; i < funcs.size(); ++i)
{
auto& func = funcs[i];
if (func)
func(args);
}
}
private:
std::vector<std::function<void(TEventArgs&)>> funcs;
};
}
#endif

47
inc/xna/csharp/screen.hpp Normal file
View File

@ -0,0 +1,47 @@
#ifndef XNA_CSHARP_SCREEN_HPP
#define XNA_CSHARP_SCREEN_HPP
#include "../default.hpp"
#include "../common/numerics.hpp"
namespace xna {
//A simplified port of System.Windows.Forms.Screen.
//Represents a display device or multiple display devices on a single system.
class Screen {
public:
Screen(intptr_t hmonitor, bool primary, Rectangle bounds, Rectangle workingArea, String const& deviceName) :
hmonitor(hmonitor), primary(primary), bounds(bounds), workingArea(workingArea), deviceName(deviceName) {}
//Gets an array of all displays on the system.
static std::vector<uptr<Screen>> AllScreens();
//Gets the bounds of the display.
constexpr Rectangle Bounds() const { return bounds; }
//Gets the working area of the display.The working area is the desktop area of
//the display, excluding taskbars, docked windows, and docked tool bars.
constexpr Rectangle WorkingArea() const { return workingArea; }
//Gets the monitor handler.
constexpr intptr_t HMonitor() const { return hmonitor; }
// Gets a value indicating whether a particular display is the primary device.
constexpr bool Primary() const { return primary; }
// Gets the device name associated with a display.
constexpr String DeviceName() const { return deviceName; }
constexpr bool operator==(Screen const& other) const {
return hmonitor == other.hmonitor;
}
private:
intptr_t hmonitor{ 0 };
bool primary{ false };
Rectangle bounds{};
Rectangle workingArea{};
String deviceName;
};
}
#endif

View File

@ -47,7 +47,8 @@ namespace xna {
class MemoryStream : public Stream {
public:
constexpr MemoryStream(std::vector<Byte> const& bytes):
_buffer(bytes), _length(bytes.size()){}
_buffer(bytes),
_length(static_cast<Int>(bytes.size())){}
~MemoryStream() override {
Close();

View File

@ -151,7 +151,7 @@ namespace xna {
class GameClock;
class GameTime;
class GameWindow;
class GraphicsDeviceInformation;
struct GraphicsDeviceInformation;
class GraphicsDeviceManager;
class IGameTime;
class IGameComponent;
@ -168,7 +168,6 @@ namespace xna {
class Effect;
class GraphicsAdapter;
class GraphicsDevice;
class GraphicsDeviceInformation;
struct PresentationParameters;
class RenderTarget2D;
class SwapChain;

View File

@ -193,19 +193,6 @@ namespace xna {
Portrait = 4,
};
enum class DisplayModeScanlineOrder {
Unspecified = 0,
Progressive = 1,
UpperFieldFirst = 2,
LowerFieldFirst = 3
};
enum class DisplayModeScaling {
Unspecified = 0,
Centered = 1,
Stretched = 2
};
enum class EffectParameterClass {
Matrix,
Object,
@ -268,8 +255,12 @@ namespace xna {
None,
};
//Identifies the set of supported devices for the game based on device capabilities.
enum class GraphicsProfile {
//Use a limited set of graphic features and capabilities, allowing the game to support the widest variety of devices, including all Windows-based computers.
Reach,
//Use the largest available set of graphic features and capabilities to target devices,
//such as an Xbox 360 console and a Windows-based computer, that have more enhanced graphic capabilities.
HiDef
};

View File

@ -4,13 +4,16 @@
#include "../default.hpp"
namespace xna {
class GraphicsDeviceInformation {
public:
struct GraphicsDeviceInformation {
GraphicsDeviceInformation() {
PresentParameters = snew<PresentationParameters>();
}
sptr<GraphicsAdapter> Adapter = nullptr;
xna::GraphicsProfile Profile{ xna::GraphicsProfile::Reach };
sptr<xna::PresentationParameters> Parameters = nullptr;
sptr<GameWindow> Window = nullptr;
};
sptr<xna::PresentationParameters> PresentParameters = nullptr;
sptr<GameWindow> Window = nullptr;
};
}
#endif

View File

@ -3,36 +3,183 @@
#include "../default.hpp"
#include "gdeviceinfo.hpp"
#include "../csharp/eventhandler.hpp"
namespace xna {
class GraphicsDeviceManager {
struct IGraphicsDeviceService {
virtual sptr<GraphicsDevice> GetGraphicsDevice() = 0;
//EventHandler<EventArgs> DeviceDisposing;
//EventHandler<EventArgs> DeviceReset;
//EventHandler<EventArgs> DeviceResetting;
//EventHandler<EventArgs> DeviceCreated;
};
class IGraphicsDeviceManager {
virtual void CreateDevice() = 0;
//virtual bool BeginDraw() = 0;
//virtual void EndDraw() = 0;
};
class GraphicsDeviceManager : public IGraphicsDeviceService, public IGraphicsDeviceManager {
public:
//Creates a new GraphicsDeviceManager and registers it to handle the configuration and management of the graphics device for the specified Game.
GraphicsDeviceManager(sptr<Game> const& game);
~GraphicsDeviceManager() {}
void ApplyChanges();
bool Initialize();
bool ToggleFullScreen();
Int PreferredBackBufferWidth() const;
Int PreferredBackBufferHeight() const;
void PreferredBackBufferWidth(Int value);
void PreferredBackBufferHeight(Int value);
public:
//Specifies the default minimum back-buffer width.
static constexpr int DefaultBackBufferWidth = 800;
//Specifies the default minimum back-buffer height.
static constexpr int DefaultBackBufferHeight = 480;
protected:
bool CreateDevice();
void ChangeDevice();
public:
//Gets the GraphicsDevice associated with the GraphicsDeviceManager.
sptr<GraphicsDevice> GetGraphicsDevice() override {
return device;
}
//Gets or sets the graphics profile, which determines the graphics feature set.
constexpr GraphicsProfile PreferredGraphicsProfile() const {
return graphicsProfile;
}
//Gets or sets the graphics profile, which determines the graphics feature set.
constexpr void PreferredGraphicsProfile(xna::GraphicsProfile value) {
graphicsProfile = value;
isDeviceDirty = true;
}
//Gets or sets a value that indicates whether the device should start in full-screen mode.
constexpr bool IsFullScreen() const {
return isFullScreen;
}
//Gets or sets a value that indicates whether the device should start in full-screen mode.
constexpr void IsFullScreen(bool value) {
isFullScreen = value;
isDeviceDirty = true;
}
//Gets or sets the format of the back buffer.
constexpr SurfaceFormat PreferredBackBufferFormat() const {
return backBufferFormat;
}
//Gets or sets the format of the back buffer.
constexpr void PreferredBackBufferFormat(SurfaceFormat value) {
backBufferFormat = value;
isDeviceDirty = true;
}
//Gets or sets the preferred back-buffer height.
constexpr Int PreferredBackBufferHeight() const {
return backBufferHeight;
}
//Gets or sets the preferred back-buffer height.
constexpr void PreferredBackBufferHeight(Int value) {
backBufferHeight = value;
isDeviceDirty = true;
}
//Gets or sets the preferred back-buffer width.
constexpr Int PreferredBackBufferWidth() const {
return backBufferWidth;
}
//Gets or sets the preferred back-buffer width.
constexpr void PreferredBackBufferWidth(Int value) {
backBufferWidth = value;
isDeviceDirty = true;
}
//Gets or sets the format of the depth stencil.
constexpr DepthFormat PreferredDepthStencilFormat() const {
return depthStencilFormat;
}
//Gets or sets the format of the depth stencil.
constexpr void PreferredDepthStencilFormat(DepthFormat value) {
depthStencilFormat = value;
isDeviceDirty = true;
}
//Gets or sets a value that indicates whether to enable a multisampled back buffer.
constexpr bool PreferMultiSampling() const {
return allowMultiSampling;
}
//Gets or sets a value that indicates whether to enable a multisampled back buffer.
constexpr void PreferMultiSampling(bool value) {
allowMultiSampling = value;
isDeviceDirty = true;
}
//Gets or sets the display orientations that are available if automatic rotation and scaling is enabled.
constexpr DisplayOrientation SupportedOrientations() const {
return supportedOrientations;
}
//Gets or sets the display orientations that are available if automatic rotation and scaling is enabled.
constexpr void SupportedOrientations(DisplayOrientation value) {
supportedOrientations = value;
isDeviceDirty = true;
}
//Gets or sets a value that indicates whether to sync to the vertical trace (vsync) when presenting the back buffer.
constexpr bool SynchronizeWithVerticalRetrace() const {
return synchronizeWithVerticalRetrace;
}
// Gets or sets a value that indicates whether to sync to the vertical trace(vsync) when presenting the back buffer.
constexpr void SynchronizeWithVerticalRetrace(bool value) {
synchronizeWithVerticalRetrace = value;
isDeviceDirty = true;
}
public:
//Applies any changes to device-related properties, changing the graphics device as necessary.
void ApplyChanges();
//Toggles between full screen and windowed mode.
bool ToggleFullScreen();
protected:
inline virtual void RankDevices(std::vector<sptr<GraphicsDeviceInformation>>& foundDevices) { RankDevicesPlatform(foundDevices); }
inline virtual sptr<GraphicsDeviceInformation> FindBestDevice(bool anySuitableDevice) { return FindBestPlatformDevice(anySuitableDevice); }
virtual bool CanResetDevice(GraphicsDeviceInformation& newDeviceInfo);
private:
sptr<Game> _game = nullptr;
Int _backBufferWidth{ DefaultBackBufferWidth };
Int _backBufferHeight{ DefaultBackBufferHeight };
bool _isDeviceDirty{ false };
sptr<GraphicsDevice> _device = nullptr;
bool _isFullScreen{ false };
GraphicsDeviceInformation _information{};
inline void CreateDevice() { ChangeDevice(true); }
void ChangeDevice(bool forceCreate);
void AddDevices(bool anySuitableDevice, std::vector<sptr<GraphicsDeviceInformation>>& foundDevices);
void AddDevices(GraphicsAdapter const& adapter, DisplayMode const& mode, sptr<GraphicsDeviceInformation>& baseDeviceInfo, std::vector<sptr<GraphicsDeviceInformation>>& foundDevices) const;
sptr<GraphicsDeviceInformation> FindBestPlatformDevice(bool anySuitableDevice);
void RankDevicesPlatform(std::vector<sptr<GraphicsDeviceInformation>>& foundDevices);
void CreateDevice(GraphicsDeviceInformation& newInfo);
void MassagePresentParameters(PresentationParameters& pp);
void ValidateGraphicsDeviceInformation(GraphicsDeviceInformation& devInfo);
private:
sptr<Game> game = nullptr;
bool isDeviceDirty{ false };
sptr<GraphicsDevice> device = nullptr;
GraphicsDeviceInformation information{};
bool isFullScreen{ false };
Int backBufferWidth{ DefaultBackBufferWidth };
Int backBufferHeight{ DefaultBackBufferHeight };
GraphicsProfile graphicsProfile{GraphicsProfile::HiDef};
DepthFormat depthStencilFormat{ DepthFormat::Depth24 };
SurfaceFormat backBufferFormat{SurfaceFormat::Color};
DisplayOrientation supportedOrientations{DisplayOrientation::Default};
bool synchronizeWithVerticalRetrace{ true };
bool useResizedBackBuffer{ false };
Int resizedBackBufferWidth{ 0 };
Int resizedBackBufferHeight{ 0 };
bool allowMultiSampling{ false };
bool inDeviceTransition{ false };
bool isReallyFullScreen{ false };
DisplayOrientation currentWindowOrientation{ DisplayOrientation::Default };
std::vector<sptr<GraphicsDeviceInformation>> foundDevices;
};
}

View File

@ -3,19 +3,57 @@
#include "../default.hpp"
#include "../common/numerics.hpp"
#include "../csharp/screen.hpp"
namespace xna {
class GameWindow {
public:
GameWindow();
~GameWindow();
String Title() const;
void Title(String const& title);
Rectangle ClientBounds() const;
intptr_t Handle() const;
//Gets the current display orientation, which reflects the physical orientation of the phone in the user's hand.
constexpr DisplayOrientation CurrentOrientation() const {
return currentOrientation;
}
//Gets and sets the title of the system window.
constexpr String Title() const {
return title;
}
//Gets and sets the title of the system window.
void Title(String const& value);
//Gets the handle to the system window.
constexpr intptr_t Handle() const {
return handle;
}
//The screen dimensions of the game window's client rectangle.
constexpr Rectangle ClientBounds() const {
return clientBounds;
}
//Gets the device name of the screen the window is currently in.
String ScreenDeviceName() const;
static uptr<Screen> ScreenFromAdapter(GraphicsAdapter const& adapter);
static uptr<Screen> ScreenFromHandle(intptr_t windowHandle);
bool IsWindowMinimized() const;
inline static constexpr Int DefaultClientWidth = 800;
inline static constexpr Int DefaultClientHeight = 480;
private:
String title;
intptr_t handle{ 0 };
Rectangle clientBounds{};
String screenDeviceName;
DisplayOrientation currentOrientation{ DisplayOrientation::Default };
public:
struct PlatformImplementation;
friend struct PlatformImplementation;
uptr<PlatformImplementation> impl = nullptr;
};
}

View File

@ -2,45 +2,95 @@
#define XNA_GRAPHICS_ADAPTER_HPP
#include "../default.hpp"
#include "displaymode.hpp"
namespace xna {
//Provides methods to retrieve and manipulate graphics adapters.
class GraphicsAdapter {
public:
GraphicsAdapter();
//Collection of available adapters on the system.
static void Adapters(std::vector<uptr<GraphicsAdapter>>& adapters);
//Retrieves a string used for presentation to the user.
String Description() const;
//Retrieves a value that is used to help identify a particular chip set.
Uint DeviceId() const;
//Retrieves a string that contains the device name.
String DeviceName() const;
//Determines if this instance of GraphicsAdapter is the default adapter.
bool IsDefaultAdapter() const;
//Retrieves the handle of the monitor
intptr_t MonitorHandle() const;
//Retrieves a value used to help identify the revision level of a particular chip set.
Uint Revision() const;
//Retrieves a value used to identify the subsystem.
Uint SubSystemId() const;
//Retrieves a value used to identify the manufacturer.
Uint VendorId() const;
//Returns a collection of supported display modes for the current adapter.
uptr<DisplayModeCollection> SupportedDisplayModes() const;
//Returns a collection of supported display modes for the current adapter.
uptr<DisplayModeCollection> SupportedDisplayModes(SurfaceFormat surfaceFormat) const;
//Gets the current display mode.
sptr<DisplayMode> CurrentDisplayMode();
//Gets the current display mode.
void CurrentDisplayMode(SurfaceFormat surfaceFormat, Uint width, Uint height);
inline sptr<DisplayMode> CurrentDisplayMode() const { return currentDisplayMode; }
//Gets the default adapter.
static uptr<GraphicsAdapter> DefaultAdapter();
//Retrieves a string used for presentation to the user.
constexpr String Description() const { return description; }
//Retrieves a value that is used to help identify a particular chip set.
constexpr Uint DeviceId() const { return deviceId; }
//Collection of available adapters on the system.
static void Adapters(std::vector<uptr<GraphicsAdapter>>& adapters);
//Retrieves a string that contains the device name.
constexpr String DeviceName() const { return deviceName; }
//Determines if this instance of GraphicsAdapter is the default adapter.
constexpr bool IsDefaultAdapter() const { return isDefault; }
//Determines if the graphics adapter is in widescreen mode.
inline bool IsWideScreen() const {
return currentDisplayMode->AspectRatio() > 1.6000000238418579;
}
//Retrieves the handle of the monitor
constexpr intptr_t MonitorHandle() const { return monitorHandle; }
//Retrieves a value used to help identify the revision level of a particular chip set.
constexpr Uint Revision() const { return revision; }
//Retrieves a value used to identify the subsystem.
constexpr Uint SubSystemId() const { return subSystemId; }
//Returns a collection of supported display modes for the current adapter.
inline sptr<DisplayModeCollection> SupportedDisplayModes() const { return supportedDisplayModes; }
//Retrieves a value used to identify the manufacturer.
constexpr Uint VendorId() const { return vendorId; }
//Gets or sets a NULL device.
static bool UseNullDevice() { return useNullDevice; }
//Gets or sets a NULL device.
static void UseNullDevice(bool value) { useNullDevice = value; }
//Gets or sets a reference device.
constexpr static bool UseReferenceDevice() { return useReferenceDevice; }
//Gets or sets a reference device.
constexpr static void UseReferenceDevice(bool value) { useReferenceDevice = value; }
//Tests to see if the adapter supports the requested profile.
bool IsProfileSupported(GraphicsProfile graphicsProfile) {
return true;
}
//Queries the adapter for support for the requested back buffer format.
bool QueryBackBufferFormat(
GraphicsProfile graphicsProfile,
SurfaceFormat format,
DepthFormat depthFormat,
Int multiSampleCount,
SurfaceFormat& selectedFormat,
DepthFormat& selectedDepthFormat,
Int& selectedMultiSampleCount
) const;
private:
String description;
Uint deviceId{0};
String deviceName;
bool isDefault{ false };
intptr_t monitorHandle{ 0 };
Uint revision{ 0 };
Uint subSystemId{ 0 };
Uint vendorId{ 0 };
sptr<DisplayMode> currentDisplayMode{ nullptr };
sptr<DisplayModeCollection> supportedDisplayModes{ nullptr };
inline static bool useNullDevice = false;
inline static bool useReferenceDevice = false;
GraphicsAdapter();
public:
struct PlatformImplementation;

View File

@ -2,6 +2,7 @@
#define XNA_GRAPHICS_DEVICE_HPP
#include "../default.hpp"
#include "presentparams.hpp"
namespace xna {
//Performs primitive-based rendering, creates resources, handles system-level variables, adjusts gamma ramp levels, and creates shaders.
@ -9,6 +10,7 @@ namespace xna {
public:
GraphicsDevice();
GraphicsDevice(GraphicsDeviceInformation const& info);
GraphicsDevice(sptr<GraphicsAdapter> const& adapter, GraphicsProfile const& graphicsProfile, sptr<PresentationParameters> const& presentationParameters);
//Gets the graphics adapter.
sptr<GraphicsAdapter> Adapter() const;
@ -32,13 +34,23 @@ namespace xna {
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();
}
void Clear(Color const& color);
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();
void Reset(sptr<PresentationParameters> const& presentationParameters, sptr<GraphicsAdapter> const& graphicsAdapter);
xna::Viewport Viewport() const;
void Viewport(xna::Viewport const& viewport);
void UseVSync(bool use);

View File

@ -2,40 +2,82 @@
#define XNA_GRAPHICS_DISPLAYMODE_HPP
#include "../default.hpp"
#include "../common/numerics.hpp"
namespace xna {
struct DisplayModeDescription;
//Flags indicating the method the raster uses to create an image on a surface
enum class DisplayModeScanlineOrder {
Unspecified = 0,
Progressive = 1,
UpperFieldFirst = 2,
LowerFieldFirst = 3
};
//Flags indicating how an image is stretched to fit a given monitor's resolution
enum class DisplayModeScaling {
Unspecified = 0,
Centered = 1,
Stretched = 2
};
struct DisplayModeRate {
constexpr DisplayModeRate() = default;
constexpr DisplayModeRate(DisplayModeScanlineOrder scanlineOrdering, DisplayModeScaling scaling, RationalNumber refreshRate, bool stereo) :
ScanlineOrdering(scanlineOrdering), Scaling(scaling), RefreshRate(refreshRate), Stereo(stereo){}
constexpr bool operator==(const DisplayModeRate& other) const {
return ScanlineOrdering == other.ScanlineOrdering && Scaling == other.Scaling && RefreshRate == other.RefreshRate;
}
//Gets the method the raster uses to create an image on a surface
DisplayModeScanlineOrder ScanlineOrdering{ DisplayModeScanlineOrder::Unspecified };
//Gets how an image is stretched to fit a given monitor's resolution
DisplayModeScaling Scaling{ DisplayModeScaling::Unspecified };
//Describing the refresh rate in hertz.
RationalNumber RefreshRate{};
//Specifies whether the full-screen display mode is stereo. TRUE if stereo; otherwise, FALSE.
bool Stereo{ false };
};
//Describes the display mode.
class DisplayMode {
public:
DisplayMode();
constexpr DisplayMode();
constexpr DisplayMode(Int width, Int height, SurfaceFormat format):
width(width), height(height), format(format){}
//Gets the aspect ratio used by the graphics device.
constexpr float AspectRatio() const {
if (Height == 0 || Width == 0)
if (height == 0 || width == 0)
return 0;
return static_cast<float>(Width) / static_cast<float>(Height);
return static_cast<float>(width) / static_cast<float>(height);
}
//Gets a value indicating the screen width, in pixels.
constexpr Int Width() const { return width; }
//Gets a value indicating the screen height, in pixels.
constexpr Int Height() const { return height; }
//Gets a value indicating the surface format of the display mode.
constexpr SurfaceFormat Format() const { return format; }
constexpr bool operator==(const DisplayMode& other) const {
return Width == other.Width
&& Height == other.Height
&& Format == other.Format;
return width == other.width
&& height == other.height
&& format == other.format;
}
public:
//Gets a value indicating the screen width, in pixels.
Int Width{ 0 };
//Gets a value indicating the screen height, in pixels.
Int Height{ 0 };
//Gets a value indicating the surface format of the display mode.
SurfaceFormat Format{ SurfaceFormat::Color };
private:
friend class GraphicsAdapter;
Int width{ 0 };
Int height{ 0 };
SurfaceFormat format{ SurfaceFormat::Color };
public:
struct PlatformImplementation;
uptr<PlatformImplementation> impl;
std::vector<DisplayModeRate> Rates;
};
//Manipulates a collection of DisplayMode structures.
@ -53,6 +95,10 @@ namespace xna {
std::vector<sptr<DisplayMode>> Query(SurfaceFormat format) const;
sptr<DisplayMode> Query(SurfaceFormat format, Uint width, Uint height) const;
constexpr size_t Count() const {
return DisplayModes.size();
}
public:
std::vector<sptr<DisplayMode>> DisplayModes;
};

View File

@ -7,12 +7,15 @@ namespace xna {
struct PresentationParameters {
constexpr PresentationParameters() = default;
Uint BackBufferWidth{ 0 };
Uint BackBufferHeight{ 0 };
Int BackBufferWidth{ 0 };
Int BackBufferHeight{ 0 };
SurfaceFormat BackBufferFormat{ SurfaceFormat::Color };
SwapEffect PresentationSwapEffect{ SwapEffect::FlipDiscard };
intptr_t DeviceWindowHandle{ 0 };
bool Fullscreen{ false };
bool IsFullscreen{ false };
Int MultiSampleCount{ 0 };
PresentInterval PresentationInterval{ PresentInterval::Default };
DepthFormat DepthStencilFormat{ DepthFormat::None };
};
}

View File

@ -154,7 +154,7 @@ namespace xna {
//Gets or sets the vertical distance (in pixels) between the base lines of two consecutive lines of text
Int LineSpacing() const;
//Gets or sets the vertical distance (in pixels) between the base lines of two consecutive lines of text
void LineSpacing(Int value);
void LineSpacing(float value);
public:
struct PlatformImplementation;

View File

@ -1,5 +1,5 @@
#ifndef XNA_XNA_DX_HPP
#define XNA_XNA_DX_HPP
#ifndef XNA_XNADX_HPP
#define XNA_XNADX_HPP
#define NOMINMAX
@ -64,6 +64,28 @@ namespace xna {
//---------------- HELPERS ----------------//
struct DxHelpers {
static constexpr RECT RectangleToDx(Rectangle const& value) {
RECT rect{};
rect.top = value.Top();
rect.left = value.Left();
rect.right = value.Right();
rect.bottom = value.Bottom();
return rect;
}
static constexpr D3D11_VIEWPORT ViewportToDx(Viewport const& value) {
D3D11_VIEWPORT _view{};
_view.TopLeftX = value.X;
_view.TopLeftY = value.Y;
_view.Width = value.Width;
_view.Height = value.Height;
_view.MinDepth = value.MinDetph;
_view.MaxDepth = value.MaxDepth;
return _view;
}
static constexpr DirectX::XMVECTOR VectorToDx(Vector2 const& value) {
DirectX::XMVECTOR v{};
@ -73,7 +95,6 @@ namespace xna {
return v;
}
static constexpr DirectX::XMVECTOR VectorToDx(Vector3 const& value) {
DirectX::XMVECTOR v{};
@ -128,7 +149,6 @@ namespace xna {
return m;
}
static constexpr DirectX::SpriteSortMode SpriteSortToDx(SpriteSortMode value) {
return static_cast<DirectX::SpriteSortMode>(static_cast<int>(value));
}
@ -342,7 +362,8 @@ namespace xna {
static constexpr TextureAddressMode TextureAddresModeToXna(D3D11_TEXTURE_ADDRESS_MODE value) {
return static_cast<TextureAddressMode>(value - 1);
}
}
};
struct PlatformInit {
@ -560,25 +581,18 @@ namespace xna {
//---------------- IMPLEMENTATIONS ----------------//
struct SpriteFont::PlatformImplementation {
uptr<DirectX::SpriteFont> _dxSpriteFont{ nullptr };
uptr<DirectX::SpriteFont> dxSpriteFont{ nullptr };
};
struct SpriteBatch::PlatformImplementation {
sptr<DirectX::SpriteBatch> _dxspriteBatch = nullptr;
sptr<DirectX::SpriteBatch> dxSpriteBatch = nullptr;
comptr<ID3D11InputLayout> dxInputLayout = nullptr;
sptr<DirectX::DX11::IEffect> effectBuffer = nullptr;
sptr<DirectX::DX11::IEffect> dxEffectBuffer = nullptr;
};
struct GraphicsAdapter::PlatformImplementation {
comptr<IDXGIAdapter1> dxadapter = nullptr;
private:
friend class GraphicsAdapter;
Uint _index{ 0 };
sptr<DisplayMode> _currentDisplayMode = nullptr;
public:
bool GetOutput(UINT slot, IDXGIOutput*& output);
comptr<IDXGIAdapter1> dxAdapter = nullptr;
comptr<IDXGIFactory1> dxFactory = nullptr;
};
struct BlendRenderTarget {
@ -606,40 +620,6 @@ namespace xna {
D3D11_DEPTH_STENCIL_DESC dxDescription{};
};
struct DisplayModeRefreshRate {
constexpr DisplayModeRefreshRate() = default;
constexpr DisplayModeRefreshRate(DXGI_RATIONAL const& dxrational) {
Numerator = dxrational.Numerator;
Denominator = dxrational.Denominator;
}
constexpr DisplayModeRefreshRate(Uint numerator, Uint denominator)
: Numerator(numerator), Denominator(denominator) {}
Uint Numerator{ 0 };
Uint Denominator{ 0 };
constexpr bool operator==(const DisplayModeRefreshRate& other) const
{
return Numerator == other.Numerator && Denominator == other.Denominator;
}
};
struct DisplayModeDescription {
DisplayModeScanlineOrder _scanlineOrdering{ DisplayModeScanlineOrder::Unspecified };
DisplayModeScaling _scaling{ DisplayModeScaling::Unspecified };
DisplayModeRefreshRate _refreshRate{};
constexpr bool operator==(const DisplayModeDescription& other) const
{
return _scanlineOrdering == other._scanlineOrdering && _scaling == other._scaling && _refreshRate == other._refreshRate;
}
};
struct DisplayMode::PlatformImplementation {
std::vector<DisplayModeDescription> Descriptions;
};
struct GamePad::PlatformImplementation {
uptr<DirectX::GamePad> _dxGamePad = unew<DirectX::GamePad>();
@ -718,6 +698,8 @@ namespace xna {
struct GameWindow::PlatformImplementation {
public:
PlatformImplementation(GameWindow* gameWindow): gameWindow(gameWindow){}
constexpr void Mode(GameWindowMode mode) {
_windowStyle = static_cast<int>(mode);
}
@ -787,7 +769,7 @@ namespace xna {
constexpr void Color(BYTE r, BYTE g, BYTE b) {
_windowColor = RGB(r, g, b);
}
}
bool Create();
bool Update();
@ -796,6 +778,7 @@ namespace xna {
private:
friend class GameWindow;
GameWindow* gameWindow = nullptr;
HINSTANCE _hInstance{ nullptr };
HWND _windowHandle{ nullptr };
@ -862,10 +845,22 @@ namespace xna {
sptr<SwapChain> _swapChain = nullptr;
sptr<GraphicsAdapter> _adapter = nullptr;
sptr<RenderTarget2D> _renderTarget2D = nullptr;
sptr<GameWindow> _gameWindow = nullptr;
intptr_t windowHandle{ 0 };
xna::Viewport _viewport{};
sptr<xna::PresentationParameters> _presentationParameters;
D3D_FEATURE_LEVEL _featureLevel{ D3D_FEATURE_LEVEL::D3D_FEATURE_LEVEL_11_0 };
D3D_FEATURE_LEVEL featureLevels[7] =
{
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1,
};
D3D_FEATURE_LEVEL currentFeatureLevel{ D3D_FEATURE_LEVEL_11_1 };
private:
friend class GraphicsDevice;

View File

@ -23,6 +23,8 @@
#include "csharp/stream.hpp"
#include "csharp/timespan.hpp"
#include "csharp/type.hpp"
#include "csharp/screen.hpp"
#include "csharp/eventhandler.hpp"
#include "exception.hpp"
#include "game/component.hpp"
#include "game/game.hpp"

View File

@ -16,8 +16,9 @@ namespace xna {
void Initialize() override {
auto game = reinterpret_cast<Game*>(this);
graphics = snew<GraphicsDeviceManager>(game->shared_from_this());
graphics->Initialize();
graphics = snew<GraphicsDeviceManager>(game->shared_from_this());
//graphics->Initialize();
graphics->ApplyChanges();
std::any device = graphicsDevice;
services->AddService(*typeof<GraphicsDevice>(), device);
@ -45,7 +46,7 @@ namespace xna {
private:
sptr<GraphicsDeviceManager> graphics = nullptr;
sptr<SpriteBatch> spriteBatch = nullptr;
sptr<Texture2D> texture = nullptr;
sptr<Texture2D> texture = nullptr;
};
}

View File

@ -14,8 +14,9 @@ namespace PlatformerStarterKit {
Center(position), Radius(radius){}
constexpr bool Intersects(xna::Rectangle const& rectangle) const {
const auto v = xna::Vector2(xna::MathHelper::Clamp(Center.X, rectangle.Left(), rectangle.Right()),
xna::MathHelper::Clamp(Center.Y, rectangle.Top(), rectangle.Bottom()));
const auto v =
xna::Vector2(xna::MathHelper::Clamp(Center.X, static_cast<float>(rectangle.Left()), static_cast<float>(rectangle.Right())),
xna::MathHelper::Clamp(Center.Y, static_cast<float>(rectangle.Top()), static_cast<float>(rectangle.Bottom())));
const auto direction = Center - v;
auto distanceSquared = direction.LengthSquared();

View File

@ -22,7 +22,7 @@ namespace PlatformerStarterKit {
void Initialize() override {
auto game = reinterpret_cast<Game*>(this);
graphics = snew<GraphicsDeviceManager>(game->shared_from_this());
graphics->Initialize();
graphics->ApplyChanges();
std::any device = graphicsDevice;
services->AddService(*typeof<GraphicsDevice>(), device);