diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 8bf3471..0ee7b6b 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/rasterizer-dx.cpp" "platform/vertexbuffer-dx.cpp" "platform/indexbuffer-dx.cpp" "common/matrix.cpp" "platform/constbuffer-dx.cpp" "platform/databuffer-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") 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 462c4ca..9a46d9b 100644 --- a/framework/enums.hpp +++ b/framework/enums.hpp @@ -40,6 +40,17 @@ namespace xna { All }; + enum class ComparisonFunction { + Never, + Less, + Equal, + LessEquals, + Greater, + NotEqual, + GreaterEqual, + Always + }; + enum class CullMode { None, CullClockwiseFace, @@ -113,6 +124,26 @@ namespace xna { HdrBlendable = 19, }; + enum class TextureAddressMode { + Wrap, + Clamp, + Mirror, + Border, + MirrorOnce + }; + + enum class TextureFilter { + Linear, + Point, + Anisotropic, + LinearMipPoint, + PointMipLinear, + MinLinearMagPointMipLinear, + MinLinearMagPointMipPoint, + MinPointMagLinearMipLinear, + MinPointMagLinearMipPoint, + }; + constexpr int SURFACE_FORMAT_COUNT = 19; } diff --git a/framework/forward.hpp b/framework/forward.hpp index 3e4e948..16fa320 100644 --- a/framework/forward.hpp +++ b/framework/forward.hpp @@ -111,6 +111,8 @@ namespace xna { using PTexture2D = std::shared_ptr; class RasterizerState; using PRasterizerState = std::shared_ptr; + class SamplerState; + using PSamplerState = std::shared_ptr; class Shader; using PShader = std::shared_ptr; class VertexBuffer; diff --git a/framework/graphics/rasterizer.hpp b/framework/graphics/rasterizerstate.hpp similarity index 100% rename from framework/graphics/rasterizer.hpp rename to framework/graphics/rasterizerstate.hpp diff --git a/framework/graphics/samplerstate.hpp b/framework/graphics/samplerstate.hpp new file mode 100644 index 0000000..339cc18 --- /dev/null +++ b/framework/graphics/samplerstate.hpp @@ -0,0 +1,38 @@ +#ifndef XNA_GRAPHICS_SAMPLERSTATE_HPP +#define XNA_GRAPHICS_SAMPLERSTATE_HPP + +#include "../default.hpp" + +namespace xna { + class ISamplerState { + public: + virtual ~ISamplerState(){} + virtual void Filter(TextureFilter value) = 0; + virtual void AddressU(TextureAddressMode value) = 0; + virtual void AddressV(TextureAddressMode value) = 0; + virtual void AddressW(TextureAddressMode value) = 0; + virtual void Comparison(ComparisonFunction value) = 0; + virtual void MipLODBias(float value) = 0; + virtual void MinLOD(float value) = 0; + virtual void MaxLOD(float value) = 0; + virtual void MaxAnisotropy(Uint value) = 0; + virtual TextureFilter Filter() const = 0; + virtual TextureAddressMode AddressU() const = 0; + virtual TextureAddressMode AddressV() const = 0; + virtual TextureAddressMode AddressW() const = 0; + virtual ComparisonFunction Comparison() const = 0; + virtual float MipLODBias() const = 0; + virtual float MinLOD() const = 0; + virtual float MaxLOD() const = 0; + virtual Uint MaxAnisotropy() const = 0; + + static PSamplerState PoinWrap(); + static PSamplerState PointClamp(); + static PSamplerState LinearWrap(); + static PSamplerState LinearClamp(); + static PSamplerState AnisotropicWrap(); + static PSamplerState AnisotropicClamp(); + }; +} + +#endif \ No newline at end of file diff --git a/framework/platform/rasterizer-dx.cpp b/framework/platform/rasterizerstate-dx.cpp similarity index 90% rename from framework/platform/rasterizer-dx.cpp rename to framework/platform/rasterizerstate-dx.cpp index dda98c1..286e4a9 100644 --- a/framework/platform/rasterizer-dx.cpp +++ b/framework/platform/rasterizerstate-dx.cpp @@ -1,4 +1,4 @@ -#include "rasterizer-dx.hpp" +#include "rasterizerstate-dx.hpp" #include "device-dx.hpp" namespace xna { diff --git a/framework/platform/rasterizer-dx.hpp b/framework/platform/rasterizerstate-dx.hpp similarity index 95% rename from framework/platform/rasterizer-dx.hpp rename to framework/platform/rasterizerstate-dx.hpp index b5ca04e..344e107 100644 --- a/framework/platform/rasterizer-dx.hpp +++ b/framework/platform/rasterizerstate-dx.hpp @@ -1,7 +1,7 @@ -#ifndef XNA_PLATFORM_RASTERIZER_DX_HPP -#define XNA_PLATFORM_RASTERIZER_DX_HPP +#ifndef XNA_PLATFORM_RASTERIZERSTATE_DX_HPP +#define XNA_PLATFORM_RASTERIZERSTATE_DX_HPP -#include "../graphics/rasterizer.hpp" +#include "../graphics/rasterizerstate.hpp" #include "dxheaders.hpp" namespace xna { diff --git a/framework/platform/samplerstate-dx.cpp b/framework/platform/samplerstate-dx.cpp new file mode 100644 index 0000000..d3f8891 --- /dev/null +++ b/framework/platform/samplerstate-dx.cpp @@ -0,0 +1,57 @@ +#include "samplerstate-dx.hpp" + +namespace xna { + PSamplerState ISamplerState::PoinWrap() { + auto state = New(); + state->_description.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + state->_description.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + state->_description.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + state->_description.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + return state; + } + + PSamplerState ISamplerState::PointClamp() { + auto state = New(); + state->_description.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + state->_description.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + state->_description.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + state->_description.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + return state; + } + + PSamplerState ISamplerState::LinearWrap() { + auto state = New(); + state->_description.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + state->_description.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + state->_description.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + state->_description.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + return state; + } + + PSamplerState ISamplerState::LinearClamp() { + auto state = New(); + state->_description.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + state->_description.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + state->_description.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + state->_description.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + return state; + } + + PSamplerState ISamplerState::AnisotropicWrap() { + auto state = New(); + state->_description.Filter = D3D11_FILTER_ANISOTROPIC; + state->_description.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + state->_description.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + state->_description.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + return state; + } + + PSamplerState ISamplerState::AnisotropicClamp() { + auto state = New(); + state->_description.Filter = D3D11_FILTER_ANISOTROPIC; + state->_description.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + state->_description.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + state->_description.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + return state; + } +} \ No newline at end of file diff --git a/framework/platform/samplerstate-dx.hpp b/framework/platform/samplerstate-dx.hpp new file mode 100644 index 0000000..711674d --- /dev/null +++ b/framework/platform/samplerstate-dx.hpp @@ -0,0 +1,251 @@ +#ifndef XNA_PLATFORM_SAMPLERSTATE_DX_HPP +#define XNA_PLATFORM_SAMPLERSTATE_DX_HPP + +#include "../graphics/samplerstate.hpp" +#include "dxheaders.hpp" + +namespace xna { + class SamplerState : public ISamplerState { + public: + SamplerState() { + _description.MaxAnisotropy = 4; + } + + virtual ~SamplerState() override { + if (_samplerState) { + _samplerState->Release(); + _samplerState = nullptr; + } + } + + virtual constexpr void Filter(TextureFilter value) override { + switch (value) + { + case xna::TextureFilter::Linear: + _description.Filter = D3D11_FILTER::D3D11_FILTER_MIN_MAG_MIP_LINEAR; + break; + case xna::TextureFilter::Point: + _description.Filter = D3D11_FILTER::D3D11_FILTER_MIN_MAG_MIP_POINT; + break; + case xna::TextureFilter::Anisotropic: + _description.Filter = D3D11_FILTER::D3D11_FILTER_ANISOTROPIC; + break; + case xna::TextureFilter::LinearMipPoint: + _description.Filter = D3D11_FILTER::D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT; + break; + case xna::TextureFilter::PointMipLinear: + _description.Filter = D3D11_FILTER::D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR; + break; + case xna::TextureFilter::MinLinearMagPointMipLinear: + _description.Filter = D3D11_FILTER::D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR; + break; + case xna::TextureFilter::MinLinearMagPointMipPoint: + _description.Filter = D3D11_FILTER::D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT; + break; + case xna::TextureFilter::MinPointMagLinearMipLinear: + _description.Filter = D3D11_FILTER::D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR; + break; + case xna::TextureFilter::MinPointMagLinearMipPoint: + _description.Filter = D3D11_FILTER::D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT; + break; + default: + break; + } + } + + virtual constexpr void AddressU(TextureAddressMode value) override { + ConvertAddressMode(value, _description.AddressU); + } + + virtual constexpr void AddressV(TextureAddressMode value) override { + ConvertAddressMode(value, _description.AddressV); + } + + virtual constexpr void AddressW(TextureAddressMode value) override { + ConvertAddressMode(value, _description.AddressW); + } + + virtual constexpr void Comparison(ComparisonFunction value) override { + switch (value) + { + case xna::ComparisonFunction::Never: + _description.ComparisonFunc = D3D11_COMPARISON_NEVER; + break; + case xna::ComparisonFunction::Less: + _description.ComparisonFunc = D3D11_COMPARISON_LESS; + break; + case xna::ComparisonFunction::Equal: + _description.ComparisonFunc = D3D11_COMPARISON_EQUAL; + break; + case xna::ComparisonFunction::LessEquals: + _description.ComparisonFunc = D3D11_COMPARISON_LESS_EQUAL; + break; + case xna::ComparisonFunction::Greater: + _description.ComparisonFunc = D3D11_COMPARISON_GREATER; + break; + case xna::ComparisonFunction::NotEqual: + _description.ComparisonFunc = D3D11_COMPARISON_NOT_EQUAL; + break; + case xna::ComparisonFunction::GreaterEqual: + _description.ComparisonFunc = D3D11_COMPARISON_GREATER_EQUAL; + break; + case xna::ComparisonFunction::Always: + _description.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + break; + default: + _description.ComparisonFunc = D3D11_COMPARISON_NEVER; + break; + } + } + + virtual constexpr void MipLODBias(float value) override { + _description.MipLODBias = value; + } + + virtual constexpr void MinLOD(float value) override { + _description.MinLOD = value; + } + + virtual constexpr void MaxLOD(float value) override { + _description.MaxLOD = value; + } + + virtual void MaxAnisotropy(Uint value) override { + _description.MaxAnisotropy = static_cast(value); + } + + virtual constexpr TextureFilter Filter() const override { + switch (_description.Filter) + { + case D3D11_FILTER::D3D11_FILTER_MIN_MAG_MIP_LINEAR: + return xna::TextureFilter::Linear; + case D3D11_FILTER_MIN_MAG_MIP_POINT: + return xna::TextureFilter::Point; + case D3D11_FILTER_ANISOTROPIC: + return xna::TextureFilter::Anisotropic; + case D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT: + return xna::TextureFilter::LinearMipPoint; + case D3D11_FILTER_MIN_MAG_POINT_MIP_LINEAR: + return xna::TextureFilter::PointMipLinear; + case D3D11_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR: + return xna::TextureFilter::MinLinearMagPointMipLinear; + case D3D11_FILTER_MIN_LINEAR_MAG_MIP_POINT: + return xna::TextureFilter::MinLinearMagPointMipPoint; + case D3D11_FILTER_MIN_POINT_MAG_MIP_LINEAR: + return xna::TextureFilter::MinPointMagLinearMipLinear; + case D3D11_FILTER_MIN_POINT_MAG_LINEAR_MIP_POINT: + return xna::TextureFilter::MinPointMagLinearMipPoint; + default: + return xna::TextureFilter::Linear; + } + } + + virtual constexpr TextureAddressMode AddressU() const override { + TextureAddressMode mode; + ConvertAddressMode(_description.AddressU, mode); + return mode; + } + + virtual constexpr TextureAddressMode AddressV() const override { + TextureAddressMode mode; + ConvertAddressMode(_description.AddressV, mode); + return mode; + } + + virtual constexpr TextureAddressMode AddressW() const override { + TextureAddressMode mode; + ConvertAddressMode(_description.AddressW, mode); + return mode; + } + + virtual ComparisonFunction Comparison() const override { + switch (_description.ComparisonFunc) + { + case D3D11_COMPARISON_NEVER : + return xna::ComparisonFunction::Never; + case D3D11_COMPARISON_LESS: + return xna::ComparisonFunction::Less; + case D3D11_COMPARISON_EQUAL: + return xna::ComparisonFunction::Equal; + case D3D11_COMPARISON_LESS_EQUAL: + return xna::ComparisonFunction::LessEquals; + case D3D11_COMPARISON_GREATER: + return xna::ComparisonFunction::Greater; + case D3D11_COMPARISON_NOT_EQUAL: + return xna::ComparisonFunction::NotEqual; + case D3D11_COMPARISON_GREATER_EQUAL: + return xna::ComparisonFunction::GreaterEqual; + case D3D11_COMPARISON_ALWAYS: + return xna::ComparisonFunction::Always; + default: + return xna::ComparisonFunction::Never; + } + } + + virtual constexpr float MipLODBias() const override { + return _description.MipLODBias; + } + + virtual constexpr float MinLOD() const override { + return _description.MinLOD; + } + + virtual constexpr float MaxLOD() const override { + return _description.MaxLOD; + } + + virtual constexpr Uint MaxAnisotropy() const override { + return _description.MaxAnisotropy; + } + + public: + ID3D11SamplerState* _samplerState = nullptr; + D3D11_SAMPLER_DESC _description{}; + + public: + static constexpr void ConvertAddressMode(TextureAddressMode value, D3D11_TEXTURE_ADDRESS_MODE& target) { + switch (value) + { + case xna::TextureAddressMode::Wrap: + target = D3D11_TEXTURE_ADDRESS_WRAP; + break; + case xna::TextureAddressMode::Clamp: + target = D3D11_TEXTURE_ADDRESS_CLAMP; + break; + case xna::TextureAddressMode::Mirror: + target = D3D11_TEXTURE_ADDRESS_MIRROR; + break; + case xna::TextureAddressMode::Border: + target = D3D11_TEXTURE_ADDRESS_BORDER; + break; + case xna::TextureAddressMode::MirrorOnce: + target = D3D11_TEXTURE_ADDRESS_MIRROR_ONCE; + break; + default: + target = D3D11_TEXTURE_ADDRESS_WRAP; + break; + } + } + + static constexpr void ConvertAddressMode(D3D11_TEXTURE_ADDRESS_MODE value, TextureAddressMode& target) { + switch (value) + { + case D3D11_TEXTURE_ADDRESS_WRAP: + target = TextureAddressMode::Wrap; + case D3D11_TEXTURE_ADDRESS_CLAMP: + target = TextureAddressMode::Clamp; + case D3D11_TEXTURE_ADDRESS_MIRROR: + target = TextureAddressMode::Mirror; + case D3D11_TEXTURE_ADDRESS_BORDER: + target = TextureAddressMode::Border; + case D3D11_TEXTURE_ADDRESS_MIRROR_ONCE: + target = TextureAddressMode::MirrorOnce; + default: + target = TextureAddressMode::Wrap; + break; + } + } + }; +} + +#endif \ No newline at end of file