diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 230ff80..0c130c3 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") +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") 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 f8c30bf..cb535da 100644 --- a/framework/enums.hpp +++ b/framework/enums.hpp @@ -64,6 +64,11 @@ namespace xna { Depth24Stencil8 }; + enum class DepthWriteMask { + Zero, + All + }; + enum class DisplayOrientation { Default = 0, LandscapeLeft = 1, @@ -117,6 +122,18 @@ namespace xna { FrontToBack, }; + enum class StencilOperation + { + Keep, + Zero, + Replace, + IncrementSaturation, + DecrementSaturation, + Invert, + Increment, + Decrement, + }; + enum class SurfaceFormat { Color = 0, Bgr565 = 1, diff --git a/framework/forward.hpp b/framework/forward.hpp index eb03b98..133284a 100644 --- a/framework/forward.hpp +++ b/framework/forward.hpp @@ -89,6 +89,8 @@ namespace xna { using PConstantBuffer = std::shared_ptr; class DataBuffer; using PDataBuffer = std::shared_ptr; + class DepthStencilState; + using PDepthStencilState = std::shared_ptr; class DisplayMode; using PDisplayMode = std::shared_ptr; class DisplayModeCollection; diff --git a/framework/graphics/depthstencilstate.hpp b/framework/graphics/depthstencilstate.hpp new file mode 100644 index 0000000..3592bb7 --- /dev/null +++ b/framework/graphics/depthstencilstate.hpp @@ -0,0 +1,49 @@ +#ifndef XNA_GRAPHICS_DEPTHSTENCILSTATE_HPP +#define XNA_GRAPHICS_DEPTHSTENCILSTATE_HPP + +#include "../default.hpp" + +namespace xna { + class IDepthStencilState { + public: + virtual ~IDepthStencilState(){} + virtual bool Initialize(GraphicsDevice& device, xna_error_nullarg) = 0; + virtual bool Apply(GraphicsDevice& device, xna_error_ptr_arg) = 0; + + virtual void DepthEnabled(bool value) = 0; + virtual void DepthWriteEnabled(bool value) = 0; + virtual void DepthCompareFunction(ComparisonFunction value) = 0; + virtual void StencilEnabled(bool value) = 0; + virtual void StencilReadMask(int value) = 0; + virtual void StencilWriteMask(int value) = 0; + virtual void StencilFrontFacePass(StencilOperation value) = 0; + virtual void StencilFrontFaceFail(StencilOperation value) = 0; + virtual void StencilFrontFaceDepthFail(StencilOperation value) = 0; + virtual void StencilFrontFaceCompare(ComparisonFunction value) = 0; + virtual void StencilBackFacePass(StencilOperation value) = 0; + virtual void StencilBackFaceFail(StencilOperation value) = 0; + virtual void StencilBackFaceDepthFail(StencilOperation value) = 0; + virtual void StencilBackFaceCompare(ComparisonFunction value) = 0; + + virtual bool DepthEnabled() = 0; + virtual bool DepthWriteEnabled() = 0; + virtual ComparisonFunction DepthCompareFunction() = 0; + virtual bool StencilEnabled() = 0; + virtual int StencilReadMask() = 0; + virtual int StencilWriteMask() = 0; + virtual StencilOperation StencilFrontFacePass() = 0; + virtual StencilOperation StencilFrontFaceFail() = 0; + virtual StencilOperation StencilFrontFaceDepthFail() = 0; + virtual ComparisonFunction StencilFrontFaceCompare() = 0; + virtual StencilOperation StencilBackFacePass() = 0; + virtual StencilOperation StencilBackFaceFail() = 0; + virtual StencilOperation StencilBackFaceDepthFail() = 0; + virtual ComparisonFunction StencilBackFaceCompare() = 0; + + static PDepthStencilState None(); + static PDepthStencilState Default(); + static PDepthStencilState DepthRead(); + }; +} + +#endif \ No newline at end of file diff --git a/framework/platform/depthstencilstate-dx.cpp b/framework/platform/depthstencilstate-dx.cpp new file mode 100644 index 0000000..7c09755 --- /dev/null +++ b/framework/platform/depthstencilstate-dx.cpp @@ -0,0 +1,67 @@ +#include "depthstencilstate-dx.hpp" +#include "device-dx.hpp" + +namespace xna { + bool DepthStencilState::Initialize(GraphicsDevice& device, xna_error_ptr_arg) + { + if (!device._device) { + xna_error_apply(err, XnaErrorCode::ARGUMENT_IS_NULL); + return false; + } + + if (_depthStencil) { + _depthStencil->Release(); + _depthStencil = nullptr; + } + + const auto hr = device._device->CreateDepthStencilState(&_description, &_depthStencil); + + if (FAILED(hr)) { + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); + return false; + } + + return true; + } + + bool DepthStencilState::Apply(GraphicsDevice& device, xna_error_ptr_arg) + { + if (!device._context) { + xna_error_apply(err, XnaErrorCode::ARGUMENT_IS_NULL); + return false; + } + + if (!_depthStencil) { + const auto init = Initialize(device, err); + if (!init) return false; + } + + device._context->OMSetDepthStencilState(_depthStencil, 0); + + return true; + } + + PDepthStencilState IDepthStencilState::None() { + auto stencil = New(); + stencil->_description.DepthEnable = false; + stencil->_description.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + + return stencil; + } + + PDepthStencilState IDepthStencilState::Default() { + auto stencil = New(); + stencil->_description.DepthEnable = true; + stencil->_description.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL; + + return stencil; + } + + PDepthStencilState IDepthStencilState::DepthRead() { + auto stencil = New(); + stencil->_description.DepthEnable = true; + stencil->_description.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + + return stencil; + } +} \ No newline at end of file diff --git a/framework/platform/depthstencilstate-dx.hpp b/framework/platform/depthstencilstate-dx.hpp new file mode 100644 index 0000000..fa70a31 --- /dev/null +++ b/framework/platform/depthstencilstate-dx.hpp @@ -0,0 +1,176 @@ +#ifndef XNA_PLATFORM_DEPTHSTENCILSTATE_DX_HPP +#define XNA_PLATFORM_DEPTHSTENCILSTATE_DX_HPP + +#include "../graphics/depthstencilstate.hpp" +#include "dxheaders.hpp" + +namespace xna { + class DepthStencilState : public IDepthStencilState { + public: + DepthStencilState() { + _description.DepthEnable = true; + _description.StencilEnable = true; + _description.DepthFunc = D3D11_COMPARISON_LESS_EQUAL; + + _description.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + _description.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + _description.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + _description.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + + _description.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS; + _description.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; + _description.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; + _description.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; + + _description.StencilReadMask = 0; + _description.StencilWriteMask = 0; + _description.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO; + } + + virtual ~DepthStencilState() override { + if (_depthStencil) { + _depthStencil->Release(); + _depthStencil = nullptr; + } + } + + virtual bool Initialize(GraphicsDevice& device, xna_error_nullarg) override; + virtual bool Apply(GraphicsDevice& device, xna_error_ptr_arg) override; + + virtual constexpr void DepthEnabled(bool value) override { + _description.DepthEnable = value; + } + + virtual constexpr void DepthWriteEnabled(bool value) override { + _description.DepthWriteMask = static_cast(value); + } + + virtual constexpr void DepthCompareFunction(ComparisonFunction value) override { + const auto _value = static_cast(value) + 1; + _description.DepthFunc = static_cast(_value); + } + + virtual constexpr void StencilEnabled(bool value) override { + _description.StencilEnable = value; + } + + virtual constexpr void StencilReadMask(int value) override { + _description.StencilReadMask = static_cast(value); + } + + virtual constexpr void StencilWriteMask(int value) override { + _description.StencilWriteMask = static_cast(value); + } + + virtual constexpr void StencilFrontFacePass(StencilOperation value) override { + const auto _value = static_cast(value) + 1; + _description.FrontFace.StencilPassOp = static_cast(_value); + } + + virtual constexpr void StencilFrontFaceFail(StencilOperation value) override { + const auto _value = static_cast(value) + 1; + _description.FrontFace.StencilFailOp = static_cast(_value); + } + + virtual constexpr void StencilFrontFaceDepthFail(StencilOperation value) override { + const auto _value = static_cast(value) + 1; + _description.FrontFace.StencilDepthFailOp = static_cast(_value); + } + + virtual constexpr void StencilFrontFaceCompare(ComparisonFunction value) override { + const auto _value = static_cast(value) + 1; + _description.FrontFace.StencilFunc = static_cast(_value); + } + + virtual constexpr void StencilBackFacePass(StencilOperation value) override { + const auto _value = static_cast(value) + 1; + _description.BackFace.StencilPassOp = static_cast(_value); + } + + virtual constexpr void StencilBackFaceFail(StencilOperation value) override { + const auto _value = static_cast(value) + 1; + _description.BackFace.StencilFailOp = static_cast(_value); + } + + virtual constexpr void StencilBackFaceDepthFail(StencilOperation value) override { + const auto _value = static_cast(value) + 1; + _description.BackFace.StencilDepthFailOp = static_cast(_value); + } + + virtual constexpr void StencilBackFaceCompare(ComparisonFunction value) override { + const auto _value = static_cast(value) + 1; + _description.BackFace.StencilFunc = static_cast(_value); + } + + virtual constexpr bool DepthEnabled() override { + return _description.DepthEnable; + } + + virtual constexpr bool DepthWriteEnabled() override { + return static_cast(_description.DepthWriteMask); + } + + virtual constexpr ComparisonFunction DepthCompareFunction() override { + const auto _value = static_cast(_description.DepthFunc) - 1; + return static_cast(_value); + } + + virtual constexpr bool StencilEnabled() override { + return _description.StencilEnable; + } + + virtual constexpr int StencilReadMask() override { + return static_cast(_description.StencilReadMask); + } + + virtual constexpr int StencilWriteMask() override { + return static_cast(_description.StencilWriteMask); + } + + virtual constexpr StencilOperation StencilFrontFacePass() override { + const auto _value = static_cast(_description.FrontFace.StencilPassOp) - 1; + return static_cast(_value); + } + + virtual constexpr StencilOperation StencilFrontFaceFail() override { + const auto _value = static_cast(_description.FrontFace.StencilFailOp) - 1; + return static_cast(_value); + } + + virtual constexpr StencilOperation StencilFrontFaceDepthFail() override { + const auto _value = static_cast(_description.FrontFace.StencilDepthFailOp) - 1; + return static_cast(_value); + } + + virtual constexpr ComparisonFunction StencilFrontFaceCompare() override { + const auto _value = static_cast(_description.FrontFace.StencilFunc) - 1; + return static_cast(_value); + } + + virtual constexpr StencilOperation StencilBackFacePass() override { + const auto _value = static_cast(_description.BackFace.StencilPassOp) - 1; + return static_cast(_value); + } + + virtual constexpr StencilOperation StencilBackFaceFail() override { + const auto _value = static_cast(_description.BackFace.StencilFailOp) - 1; + return static_cast(_value); + } + + virtual constexpr StencilOperation StencilBackFaceDepthFail() override { + const auto _value = static_cast(_description.BackFace.StencilDepthFailOp) - 1; + return static_cast(_value); + } + + virtual constexpr ComparisonFunction StencilBackFaceCompare() override { + const auto _value = static_cast(_description.BackFace.StencilFunc) - 1; + return static_cast(_value); + } + + public: + ID3D11DepthStencilState* _depthStencil = nullptr; + D3D11_DEPTH_STENCIL_DESC _description{}; + }; +} + +#endif \ No newline at end of file