diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index ad2eb1f..b671a97 100644 --- a/framework/CMakeLists.txt +++ b/framework/CMakeLists.txt @@ -3,7 +3,7 @@ # # Add source to this project's executable. -add_executable (xna WIN32 "xna.cpp" "xna.h" "platform/window-dx.cpp" "platform/device-dx.cpp" "platform/adapter-dx.cpp" "platform/swapchain-dx.cpp" "platform/rendertarget-dx.cpp" "platform/texture-dx.cpp" "platform/blendstate-dx.cpp" "platform/game-dx.cpp" "platform/clock-dx.cpp" "csharp/stream.cpp" "platform/gdevicemanager-dx.cpp" "platform/vertexinput-dx.cpp" "platform/shader-dx.cpp" "platform/rasterizerstate-dx.cpp" "platform/vertexbuffer-dx.cpp" "platform/indexbuffer-dx.cpp" "common/matrix.cpp" "platform/constbuffer-dx.cpp" "platform/databuffer-dx.cpp" "platform/samplerstate-dx.cpp" "platform/spritebatch-dx.cpp" "platform/spritefont-dx.cpp" "platform/depthstencilstate-dx.cpp" "platform/keyboard-dx.cpp" "platform/mouse-dx.cpp" "platform/gamepad-dx.cpp" "common/vectors.cpp" "platform/soundeffect-dx.cpp") +add_executable (xna WIN32 "xna.cpp" "xna.h" "platform/window-dx.cpp" "platform/device-dx.cpp" "platform/adapter-dx.cpp" "platform/swapchain-dx.cpp" "platform/rendertarget-dx.cpp" "platform/texture-dx.cpp" "platform/blendstate-dx.cpp" "platform/game-dx.cpp" "platform/clock-dx.cpp" "csharp/stream.cpp" "platform/gdevicemanager-dx.cpp" "platform/vertexinput-dx.cpp" "platform/shader-dx.cpp" "platform/rasterizerstate-dx.cpp" "platform/vertexbuffer-dx.cpp" "platform/indexbuffer-dx.cpp" "common/matrix.cpp" "platform/constbuffer-dx.cpp" "platform/databuffer-dx.cpp" "platform/samplerstate-dx.cpp" "platform/spritebatch-dx.cpp" "platform/spritefont-dx.cpp" "platform/depthstencilstate-dx.cpp" "platform/keyboard-dx.cpp" "platform/mouse-dx.cpp" "platform/gamepad-dx.cpp" "common/vectors.cpp" "platform/soundeffect-dx.cpp" "platform/displaymode-dx.cpp") if (CMAKE_VERSION VERSION_GREATER 3.12) set_property(TARGET xna PROPERTY CXX_STANDARD 20) diff --git a/framework/enums.hpp b/framework/enums.hpp index 7724e16..24bcf54 100644 --- a/framework/enums.hpp +++ b/framework/enums.hpp @@ -145,6 +145,19 @@ 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 FillMode { Solid, @@ -421,6 +434,7 @@ namespace xna { HalfVector2 = 17, HalfVector4 = 18, HdrBlendable = 19, + Unknown, }; enum class TextureAddressMode { diff --git a/framework/forward.hpp b/framework/forward.hpp index e811416..b659d89 100644 --- a/framework/forward.hpp +++ b/framework/forward.hpp @@ -98,6 +98,7 @@ namespace xna { using PDepthStencilState = std::shared_ptr; class DisplayMode; using PDisplayMode = std::shared_ptr; + using UDisplayMode = std::unique_ptr; class DisplayModeCollection; using PDisplayModeCollection = std::shared_ptr; using UDisplayModeCollection = std::unique_ptr; diff --git a/framework/graphics/adapter.hpp b/framework/graphics/adapter.hpp index 14aac19..976c9e7 100644 --- a/framework/graphics/adapter.hpp +++ b/framework/graphics/adapter.hpp @@ -20,10 +20,11 @@ namespace xna { virtual Uint SubSystemId() const = 0; virtual Uint VendorId() const = 0; virtual UDisplayModeCollection SupportedDisplayModes() const = 0; + virtual UDisplayMode CurrentDisplayMode() const = 0; static UGraphicsAdapter DefaultAdapter(); - static void GetAllAdapters(std::vector& adapters); - static void GetAllAdapters(std::vector& adapters); + static void Adapters(std::vector& adapters); + static void Adapters(std::vector& adapters); }; } diff --git a/framework/graphics/displaymode.hpp b/framework/graphics/displaymode.hpp index e1c4142..a2a0f1b 100644 --- a/framework/graphics/displaymode.hpp +++ b/framework/graphics/displaymode.hpp @@ -1,93 +1,27 @@ #ifndef XNA_GRAPHICS_DISPLAYMODE_HPP #define XNA_GRAPHICS_DISPLAYMODE_HPP -#include "../enums.hpp" -#include "../types.hpp" -#include "../forward.hpp" +#include "../default.hpp" namespace xna { - class DisplayMode { + struct DisplayModeDescription; + + class IDisplayMode { public: - constexpr DisplayMode() = default; - - constexpr DisplayMode(Int width, Int height, SurfaceFormat format) - : _width(width), _height(height), _format(format) {} - - constexpr float AspectRatio() const noexcept { - if (_height == 0 || _width == 0) - return 0; - - return static_cast(_width) / static_cast(_height); - } - - constexpr Int Width() const { - return _width; - } - - constexpr Int Height() const { - return _height; - } - - constexpr SurfaceFormat Format() const { - return _format; - } + virtual ~IDisplayMode() {} + virtual float AspectRatio() const = 0; + virtual Int Width() const = 0; + virtual Int Height() const = 0; + virtual SurfaceFormat Format() const = 0; + virtual std::vector Descriptions() const = 0; + }; + class IDisplayModeCollection { public: - Int _width{ 0 }; - Int _height{ 0 }; - SurfaceFormat _format{ SurfaceFormat::Color }; - }; - - class DisplayModeCollection { - public: - constexpr DisplayModeCollection() = default; - - DisplayModeCollection(size_t count) : _displayModes(count){} - - DisplayModeCollection(std::vector const& displayModes) : - _displayModes(displayModes) {} - - std::vector At(SurfaceFormat format) const { - std::vector modes; - At(format, modes); - return modes; - } - - void At(SurfaceFormat format, std::vector& modes) const { - size_t counter = 0; - - for (size_t i = 0; i < _displayModes.size(); ++i) { - const auto& displayMode = _displayModes[i]; - - if (displayMode.Format() == format) - { - modes.push_back(displayMode); - ++counter; - } - } - - if (!modes.empty()) - modes.resize(counter); - } - - size_t SurfaceCount(SurfaceFormat format) const { - size_t counter = 0; - - for (size_t i = 0; i < _displayModes.size(); ++i) { - if (_displayModes[i].Format() == format) { - ++counter; - } - } - - return counter; - } - - std::vector operator[](SurfaceFormat format) const { - return At(format); - } - - public: - std::vector _displayModes; + virtual ~IDisplayModeCollection() {} + virtual std::vector At(SurfaceFormat format) const = 0; + virtual void At(SurfaceFormat format, std::vector& modes) const = 0; + virtual size_t SurfaceCount(SurfaceFormat format) const = 0; }; } diff --git a/framework/platform/adapter-dx.cpp b/framework/platform/adapter-dx.cpp index 8e015d9..61a367c 100644 --- a/framework/platform/adapter-dx.cpp +++ b/framework/platform/adapter-dx.cpp @@ -26,7 +26,7 @@ namespace xna { return nullptr; } - void IGraphicsAdapter::GetAllAdapters(std::vector& adapters){ + void IGraphicsAdapter::Adapters(std::vector& adapters){ IDXGIFactory1* pFactory = nullptr; if FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory)) @@ -48,7 +48,7 @@ namespace xna { pFactory = nullptr; } - void IGraphicsAdapter::GetAllAdapters(std::vector& adapters) { + void IGraphicsAdapter::Adapters(std::vector& adapters) { IDXGIFactory1* pFactory = nullptr; if FAILED(CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&pFactory)) @@ -180,18 +180,50 @@ namespace xna { pOutput->Release(); - auto collection = uNew(totalModes); + auto collection = uNew(); + DisplayMode currentDisplayMode{}; + std::vector displayList; + PDisplayMode pDisplay = nullptr; + size_t displayCount = 0; for (size_t i = 0; i < totalModes; ++i) { - const auto& modedesc = buffer[i]; - const auto surface = GraphicsAdapter::ToSurface(modedesc.Format); + auto& modedesc = buffer[i]; - collection->_displayModes[i] = DisplayMode(modedesc.Width, modedesc.Height, surface); - } + DisplayModeDescription description; + description._refreshRate = modedesc.RefreshRate; + description._scaling = static_cast(modedesc.Scaling); + description._scanlineOrdering = static_cast(modedesc.ScanlineOrdering); + + if (pDisplay && pDisplay->_width == modedesc.Width && pDisplay->_height == modedesc.Height && pDisplay->_format == GraphicsAdapter::ToSurface(modedesc.Format)) { + pDisplay->_descriptions.push_back(description); + } + else { + pDisplay = New(); + pDisplay->_width = modedesc.Width; + pDisplay->_height = modedesc.Height; + pDisplay->_format = GraphicsAdapter::ToSurface(modedesc.Format); + pDisplay->_descriptions.push_back(description); + displayList.push_back(pDisplay); + } + } + + collection->_displayModes = displayList; return std::move(collection); } return nullptr; - } + } + + UDisplayMode GraphicsAdapter::CurrentDisplayMode() const { + if (!_adapter) return nullptr; + IDXGIOutput* pOutput = nullptr; + + if (_adapter->EnumOutputs(0, &pOutput) != DXGI_ERROR_NOT_FOUND) { + pOutput->Release(); + } + + return nullptr; + } + } \ No newline at end of file diff --git a/framework/platform/adapter-dx.hpp b/framework/platform/adapter-dx.hpp index 0fb21ea..efb3050 100644 --- a/framework/platform/adapter-dx.hpp +++ b/framework/platform/adapter-dx.hpp @@ -2,6 +2,7 @@ #define XNA_PLATFORM_ADAPTER_DX_HPP #include "../graphics/adapter.hpp" +#include "displaymode-dx.hpp" #include "dxheaders.hpp" namespace xna { @@ -27,6 +28,7 @@ namespace xna { virtual Uint VendorId() const override; virtual UDisplayModeCollection SupportedDisplayModes() const override; virtual constexpr bool IsDefaultAdapter() const { return _index == 0; } + virtual UDisplayMode CurrentDisplayMode() const override; public: IDXGIAdapter1* _adapter{ nullptr }; @@ -123,7 +125,7 @@ namespace xna { case DXGI_FORMAT_R16G16B16A16_FLOAT: return SurfaceFormat::HalfVector4; default: - return SurfaceFormat::Color; + return SurfaceFormat::Unknown; } } }; diff --git a/framework/platform/device-dx.hpp b/framework/platform/device-dx.hpp index 83567cf..f00f1c2 100644 --- a/framework/platform/device-dx.hpp +++ b/framework/platform/device-dx.hpp @@ -3,6 +3,12 @@ #include "../graphics/device.hpp" #include "../graphics/presentparams.hpp" +#include "adapter-dx.hpp" +#include "gdeviceinfo-dx.hpp" +#include "../common/color.hpp" +#include "window-dx.hpp" +#include "../graphics/viewport.hpp" +#include "swapchain-dx.hpp" #include "dxgi.h" #include "d3d11.h" diff --git a/framework/platform/displaymode-dx.cpp b/framework/platform/displaymode-dx.cpp new file mode 100644 index 0000000..3f99ac9 --- /dev/null +++ b/framework/platform/displaymode-dx.cpp @@ -0,0 +1 @@ +#include "displaymode-dx.hpp" \ No newline at end of file diff --git a/framework/platform/displaymode-dx.hpp b/framework/platform/displaymode-dx.hpp new file mode 100644 index 0000000..0997379 --- /dev/null +++ b/framework/platform/displaymode-dx.hpp @@ -0,0 +1,135 @@ +#ifndef XNA_PLATFORM_DISPLAYMODE_DX_HPP +#define XNA_PLATFORM_DISPLAYMODE_DX_HPP + +#include "../graphics/displaymode.hpp" +#include "dxheaders.hpp" + +namespace xna { + 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; + } + }; + + class DisplayMode : public IDisplayMode { + public: + constexpr DisplayMode() = default; + + constexpr DisplayMode(Int width, Int height, SurfaceFormat format) + : _width(width), _height(height), _format(format) {} + + virtual constexpr float AspectRatio() const noexcept override { + if (_height == 0 || _width == 0) + return 0; + + return static_cast(_width) / static_cast(_height); + } + + virtual constexpr Int Width() const override { + return _width; + } + + virtual constexpr Int Height() const override { + return _height; + } + + virtual constexpr SurfaceFormat Format() const override { + return _format; + } + + virtual constexpr std::vector Descriptions() const { + return _descriptions; + } + + public: + Int _width{ 0 }; + Int _height{ 0 }; + SurfaceFormat _format{ SurfaceFormat::Color }; + std::vector _descriptions; + + constexpr bool operator==(const DisplayMode& other) const { + return _width == other._width + && _height == other._height + && _format == other._format + && _descriptions == other._descriptions; + } + }; + + class DisplayModeCollection : public IDisplayModeCollection { + public: + constexpr DisplayModeCollection() = default; + + DisplayModeCollection(size_t count) : _displayModes(count) {} + + DisplayModeCollection(std::vector const& displayModes) : + _displayModes(displayModes) {} + + std::vector At(SurfaceFormat format) const { + std::vector modes; + At(format, modes); + return modes; + } + + void At(SurfaceFormat format, std::vector& modes) const { + size_t counter = 0; + + for (size_t i = 0; i < _displayModes.size(); ++i) { + const auto& displayMode = _displayModes[i]; + + if (displayMode->Format() == format) + { + modes.push_back(displayMode); + ++counter; + } + } + + if (!modes.empty()) + modes.resize(counter); + } + + size_t SurfaceCount(SurfaceFormat format) const { + size_t counter = 0; + + for (size_t i = 0; i < _displayModes.size(); ++i) { + if (_displayModes[i]->Format() == format) { + ++counter; + } + } + + return counter; + } + + std::vector operator[](SurfaceFormat format) const { + return At(format); + } + + public: + std::vector _displayModes; + }; +} + +#endif \ No newline at end of file diff --git a/framework/platform/dxheaders.hpp b/framework/platform/dxheaders.hpp index 27c5d19..e7b4394 100644 --- a/framework/platform/dxheaders.hpp +++ b/framework/platform/dxheaders.hpp @@ -1,5 +1,7 @@ #include "dxgi.h" #include "d3d11.h" +#include +#include #include #include #define NOMINMAX diff --git a/framework/xna.cpp b/framework/xna.cpp index ef871ce..9853fc6 100644 --- a/framework/xna.cpp +++ b/framework/xna.cpp @@ -20,7 +20,8 @@ public: } void Initialize() override { - graphics->Initialize(); + graphics->Initialize(); + const auto modes= _graphicsDevice->Adapter()->SupportedDisplayModes(); Game::Initialize(); } diff --git a/framework/xna.h b/framework/xna.h index 7158cad..d068113 100644 --- a/framework/xna.h +++ b/framework/xna.h @@ -19,5 +19,6 @@ #include "platform/mouse-dx.hpp" #include "platform/gamepad-dx.hpp" #include "platform/audioengine-dx.hpp" +#include "platform/adapter-dx.hpp" // TODO: Reference additional headers your program requires here.