diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt index 0ee7b6b..c363d0b 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") +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") if (CMAKE_VERSION VERSION_GREATER 3.12) set_property(TARGET xna PROPERTY CXX_STANDARD 20) diff --git a/framework/common/color.hpp b/framework/common/color.hpp index cba2c67..a366598 100644 --- a/framework/common/color.hpp +++ b/framework/common/color.hpp @@ -2,16 +2,361 @@ #define XNA_COMMON_COLOR_HPP #include "../default.hpp" +#include "packedvalue.hpp" namespace xna { - struct Color { + struct Color : public IPackedVector, public IPackedVectorT { constexpr Color() = default; - Uint packedValue{0}; + constexpr Color(Uint packedValue) + : _packedValue(packedValue) {} - constexpr bool operator==(const Color& other) const { - return packedValue == other.packedValue; + constexpr Color(Int r, Int g, Int b, Int a = 255U) { + if (((r | g | b | a) & -256) != 0) + { + r = ClampToByte32(r); + g = ClampToByte32(g); + b = ClampToByte32(b); + a = ClampToByte32(a); + } + + g <<= 8; + b <<= 16; + a <<= 24; + + _packedValue = static_cast(r | g | b | a); } + + Color(float r, float g, float b, float a = 1.0F) : + _packedValue(PackHelper(r, g, b, a)) { + } + + Color(Vector3 const& vector) : + _packedValue(PackHelper(vector.X, vector.Y, vector.Z, 1.0F)) { + } + + Color(Vector4 const& vector) : + _packedValue(PackHelper(vector.X, vector.Y, vector.Z, vector.W)) { + } + + virtual void PackFromVector4(Vector4 const& vector) override { + _packedValue = PackHelper(vector.X, vector.Y, vector.Z, vector.W); + } + + static Color FromNonPremultiplied(Vector4 const& vector) { + Color color; + color._packedValue = PackHelper(vector.X * vector.W, vector.Y * vector.W, vector.Z * vector.W, vector.W); + return color; + } + + static Color FromNonPremultiplied(Int r, Int g, Int b, Int a) { + r = ClampToByte32(r * a / ByteMaxValue); + g = ClampToByte32(g * a / ByteMaxValue); + b = ClampToByte32(b * a / ByteMaxValue); + a = ClampToByte32(a); + g <<= 8; + b <<= 16; + a <<= 24; + + Color color; + color._packedValue = static_cast(r | g | b | a); + return color; + } + + constexpr Vector3 ToVector3() const { + Vector3 vector3; + const auto byteMax = static_cast(ByteMaxValue); + vector3.X = PackUtils::UnpackUNorm(byteMax, _packedValue); + vector3.Y = PackUtils::UnpackUNorm(byteMax, _packedValue >> 8); + vector3.Z = PackUtils::UnpackUNorm(byteMax, _packedValue >> 16); + return vector3; + } + + constexpr virtual Vector4 ToVector4() const override { + Vector4 vector4; + const auto byteMax = static_cast(ByteMaxValue); + vector4.X = PackUtils::UnpackUNorm(byteMax, _packedValue); + vector4.Y = PackUtils::UnpackUNorm(byteMax, _packedValue >> 8); + vector4.Z = PackUtils::UnpackUNorm(byteMax, _packedValue >> 16); + vector4.W = PackUtils::UnpackUNorm(byteMax, _packedValue >> 24); + return vector4; + } + + constexpr Byte R() const { + return static_cast(_packedValue); + } + + constexpr void R(Byte value) { + _packedValue = _packedValue & (UintMaxValue - 255) | static_cast(value); + } + + constexpr Byte G() const { + return static_cast(_packedValue >> 8); + } + + constexpr void G(Byte value) { + _packedValue = (static_cast(_packedValue) & -65281 | static_cast(value) << 8); + } + + constexpr Byte B() const { + return static_cast(_packedValue >> 16); + } + + constexpr void B(Byte value) { + _packedValue = (static_cast(_packedValue) & -16711681 | static_cast(value) << 16); + } + + constexpr Byte A() const { + return static_cast(_packedValue >> 24); + } + + constexpr void A(Byte value) { + _packedValue = (static_cast(_packedValue) & 16777215 | static_cast(value) << 24); + } + + virtual constexpr Uint PackedValue() const override { + return _packedValue; + } + + virtual constexpr void PackedValue(Uint const& value) override { + _packedValue = value; + } + + static Color Lerp(Color const& value1, Color const& value2, float amount) { + const Int r1 = value1.R(); + const Int g1 = value1.G(); + const Int b1 = value1.B(); + const Int a1 = value1.A(); + const Int r2 = value2.R(); + const Int g2 = value2.G(); + const Int b2 = value2.B(); + const Int a2 = value2.A(); + + const auto bitmask = static_cast(PackUtils::PackUNorm(65536.0f, amount)); + + const Int r = r1 + ((r2 - r1) * bitmask >> 16); + const Int g = g1 + ((g2 - g1) * bitmask >> 16); + const Int b = b1 + ((b2 - b1) * bitmask >> 16); + const Int a = a1 + ((a2 - a1) * bitmask >> 16); + + Color color; + color._packedValue = static_cast(r | g << 8 | b << 16 | a << 24); + return color; + } + + static constexpr Color Multiply(Color const& value, float scale) { + const Uint r = value.R(); + const Uint g = value.G(); + const Uint b = value.B(); + const Uint a = value.A(); + + scale *= 65536.0f; + + const Uint num5 = scale >= 0.0F ? (scale <= 16777215.0F ? static_cast(scale) : 16777215U) : 0U; + + Uint r1 = r * num5 >> 16; + Uint g1 = g * num5 >> 16; + Uint b1 = b * num5 >> 16; + Uint a1 = a * num5 >> 16; + + if (r1 > ByteMaxValue) + r1 = ByteMaxValue; + + if (g1 > ByteMaxValue) + g1 = ByteMaxValue; + + if (b1 > ByteMaxValue) + b1 = ByteMaxValue; + + if (a1 > ByteMaxValue) + a1 = ByteMaxValue; + + const auto r2 = static_cast(r1); + const auto g2 = static_cast(g1); + const auto b2 = static_cast(b1); + const auto a2 = static_cast(a1); + + Color color; + color._packedValue = static_cast(r2 | g2 << 8 | b2 << 16 | a2 << 24); + return color; + } + + constexpr bool operator==(Color const& other) const { + return _packedValue == other._packedValue; + } + + friend constexpr Color operator*(Color const& value, float const& scale) { + return Color::Multiply(value, scale); + } + + private: + Uint _packedValue{ 0 }; + + static constexpr Int ClampToByte32(Int value) noexcept { + if (value < 0) + return 0; + + return value > ByteMaxValue ? ByteMaxValue : value; + } + + static Uint PackHelper(float vectorX, float vectorY, float vectorZ, float vectorW) { + const auto byteMax = static_cast(ByteMaxValue); + const auto x = PackUtils::PackUNorm(byteMax, vectorX); + const auto y = PackUtils::PackUNorm(byteMax, vectorY) << 8; + const auto z = PackUtils::PackUNorm(byteMax, vectorZ); + const auto w = PackUtils::PackUNorm(byteMax, vectorW) << 24; + + return x | y | z | w; + } + }; + + struct Colors { + static constexpr Color Transparent{ Color(0U) }; + static constexpr Color AliceBlue{ Color(4294965488U) }; + static constexpr Color AntiqueWhite{ Color(4292340730U) }; + static constexpr Color Aqua{ Color(4294967040U) }; + static constexpr Color Aquamarine{ Color(4292149119U) }; + static constexpr Color Azure{ Color(4294967280U) }; + static constexpr Color Beige{ Color(4292670965U) }; + static constexpr Color Bisque{ Color(4291093759U) }; + static constexpr Color Black{ Color(4278190080U) }; + static constexpr Color BlanchedAlmond{ Color(4291685375U) }; + static constexpr Color Blue{ Color(4294901760U) }; + static constexpr Color BlueViolet{ Color(4293012362U) }; + static constexpr Color Brown{ Color(4280953509U) }; + static constexpr Color BurlyWood{ Color(4287084766U) }; + static constexpr Color CadetBlue{ Color(4288716383U) }; + static constexpr Color Chartreuse{ Color(4278255487U) }; + static constexpr Color Chocolate{ Color(4280183250U) }; + static constexpr Color Coral{ Color(4283465727U) }; + static constexpr Color CornflowerBlue{ Color(4293760356U) }; + static constexpr Color Cornsilk{ Color(4292671743U) }; + static constexpr Color Crimson{ Color(4282127580U) }; + static constexpr Color Cyan{ Color(4294967040U) }; + static constexpr Color DarkBlue{ Color(4287299584U) }; + static constexpr Color DarkCyan{ Color(4287335168U) }; + static constexpr Color DarkGoldenrod{ Color(4278945464U) }; + static constexpr Color DarkGray{ Color(4289309097U) }; + static constexpr Color DarkGreen{ Color(4278215680U) }; + static constexpr Color DarkKhaki{ Color(4285249469U) }; + static constexpr Color DarkMagenta{ Color(4287299723U) }; + static constexpr Color DarkOliveGreen{ Color(4281297749U) }; + static constexpr Color DarkOrange{ Color(4278226175U) }; + static constexpr Color DarkOrchid{ Color(4291572377U) }; + static constexpr Color DarkRed{ Color(4278190219U) }; + static constexpr Color DarkSalmon{ Color(4286224105U) }; + static constexpr Color DarkSeaGreen{ Color(4287347855U) }; + static constexpr Color DarkSlateBlue{ Color(4287315272U) }; + static constexpr Color DarkSlateGray{ Color(4283387695U) }; + static constexpr Color DarkTurquoise{ Color(4291939840U) }; + static constexpr Color DarkViolet{ Color(4292018324U) }; + static constexpr Color DeepPink{ Color(4287829247U) }; + static constexpr Color DeepSkyBlue{ Color(4294950656U) }; + static constexpr Color DimGray{ Color(4285098345U) }; + static constexpr Color DodgerBlue{ Color(4294938654U) }; + static constexpr Color Firebrick{ Color(4280427186U) }; + static constexpr Color FloralWhite{ Color(4293982975U) }; + static constexpr Color ForestGreen{ Color(4280453922U) }; + static constexpr Color Fuchsia{ Color(4294902015U) }; + static constexpr Color Gainsboro{ Color(4292664540U) }; + static constexpr Color GhostWhite{ Color(4294965496U) }; + static constexpr Color Gold{ Color(4278245375U) }; + static constexpr Color Goldenrod{ Color(4280329690U) }; + static constexpr Color Gray{ Color(4286611584U) }; + static constexpr Color Green{ Color(4278222848U) }; + static constexpr Color GreenYellow{ Color(4281335725U) }; + static constexpr Color Honeydew{ Color(4293984240U) }; + static constexpr Color HotPink{ Color(4290013695U) }; + static constexpr Color IndianRed{ Color(4284243149U) }; + static constexpr Color Indigo{ Color(4286709835U) }; + static constexpr Color Ivory{ Color(4293984255U) }; + static constexpr Color Khaki{ Color(4287424240U) }; + static constexpr Color Lavender{ Color(4294633190U) }; + static constexpr Color LavenderBlush{ Color(4294308095U) }; + static constexpr Color LawnGreen{ Color(4278254716U) }; + static constexpr Color LemonChiffon{ Color(4291689215U) }; + static constexpr Color LightBlue{ Color(4293318829U) }; + static constexpr Color LightCoral{ Color(4286611696U) }; + static constexpr Color LightCyan{ Color(4294967264U) }; + static constexpr Color LightGoldenrodYellow{ Color(4292016890U) }; + static constexpr Color LightGreen{ Color(4287688336U) }; + static constexpr Color LightGray{ Color(4292072403U) }; + static constexpr Color LightPink{ Color(4290885375U) }; + static constexpr Color LightSalmon{ Color(4286226687U) }; + static constexpr Color LightSeaGreen{ Color(4289376800U) }; + static constexpr Color LightSkyBlue{ Color(4294626951U) }; + static constexpr Color LightSlateGray{ Color(4288252023U) }; + static constexpr Color LightSteelBlue{ Color(4292789424U) }; + static constexpr Color LightYellow{ Color(4292935679U) }; + static constexpr Color Lime{ Color(4278255360U) }; + static constexpr Color LimeGreen{ Color(4281519410U) }; + static constexpr Color Linen{ Color(4293325050U) }; + static constexpr Color Magenta{ Color(4294902015U) }; + static constexpr Color Maroon{ Color(4278190208U) }; + static constexpr Color MediumAquamarine{ Color(4289383782U) }; + static constexpr Color MediumBlue{ Color(4291624960U) }; + static constexpr Color MediumOrchid{ Color(4292040122U) }; + static constexpr Color MediumPurple{ Color(4292571283U) }; + static constexpr Color MediumSeaGreen{ Color(4285641532U) }; + static constexpr Color MediumSlateBlue{ Color(4293814395U) }; + static constexpr Color MediumSpringGreen{ Color(4288346624U) }; + static constexpr Color MediumTurquoise{ Color(4291613000U) }; + static constexpr Color MediumVioletRed{ Color(4286911943U) }; + static constexpr Color MidnightBlue{ Color(4285536537U) }; + static constexpr Color MintCream{ Color(4294639605U) }; + static constexpr Color MistyRose{ Color(4292994303U) }; + static constexpr Color Moccasin{ Color(4290110719U) }; + static constexpr Color NavajoWhite{ Color(4289584895U) }; + static constexpr Color Navy{ Color(4286578688U) }; + static constexpr Color OldLace{ Color(4293326333U) }; + static constexpr Color Olive{ Color(4278222976U) }; + static constexpr Color OliveDrab{ Color(4280520299U) }; + static constexpr Color Orange{ Color(4278232575U) }; + static constexpr Color OrangeRed{ Color(4278207999U) }; + static constexpr Color Orchid{ Color(4292243674U) }; + static constexpr Color PaleGoldenrod{ Color(4289390830U) }; + static constexpr Color PaleGreen{ Color(4288215960U) }; + static constexpr Color PaleTurquoise{ Color(4293848751U) }; + static constexpr Color PaleVioletRed{ Color(4287852763U) }; + static constexpr Color PapayaWhip{ Color(4292210687U) }; + static constexpr Color PeachPuff{ Color(4290370303U) }; + static constexpr Color Peru{ Color(4282353101U) }; + static constexpr Color Pink{ Color(4291543295U) }; + static constexpr Color Plum{ Color(4292714717U) }; + static constexpr Color PowderBlue{ Color(4293320880U) }; + static constexpr Color Purple{ Color(4286578816U) }; + static constexpr Color Red{ Color(4278190335U) }; + static constexpr Color RosyBrown{ Color(4287598524U) }; + static constexpr Color RoyalBlue{ Color(4292962625U) }; + static constexpr Color SaddleBrown{ Color(4279453067U) }; + static constexpr Color Salmon{ Color(4285694202U) }; + static constexpr Color SandyBrown{ Color(4284523764U) }; + static constexpr Color SeaGreen{ Color(4283927342U) }; + static constexpr Color SeaShell{ Color(4293850623U) }; + static constexpr Color Sienna{ Color(4281160352U) }; + static constexpr Color Silver{ Color(4290822336U) }; + static constexpr Color SkyBlue{ Color(4293643911U) }; + static constexpr Color SlateBlue{ Color(4291648106U) }; + static constexpr Color SlateGray{ Color(4287660144U) }; + static constexpr Color Snow{ Color(4294638335U) }; + static constexpr Color SpringGreen{ Color(4286578432U) }; + static constexpr Color SteelBlue{ Color(4290019910U) }; + static constexpr Color Tan{ Color(4287411410U) }; + static constexpr Color Teal{ Color(4286611456U) }; + static constexpr Color Thistle{ Color(4292394968U) }; + static constexpr Color Tomato{ Color(4282868735U) }; + static constexpr Color Turquoise{ Color(4291878976U) }; + static constexpr Color Violet{ Color(4293821166U) }; + static constexpr Color Wheat{ Color(4289978101U) }; + static constexpr Color White{ Color(UintMaxValue) }; + static constexpr Color WhiteSmoke{ Color(4294309365U) }; + static constexpr Color Yellow{ Color(4278255615U) }; + static constexpr Color YellowGreen{ Color(4281519514U) }; + + private: + constexpr Colors() = default; + constexpr Colors(Colors&&) = default; + constexpr Colors(const Colors&) = default; }; } diff --git a/framework/common/packedvalue.hpp b/framework/common/packedvalue.hpp new file mode 100644 index 0000000..bb43a40 --- /dev/null +++ b/framework/common/packedvalue.hpp @@ -0,0 +1,84 @@ +#ifndef CXNA_COMMON_PACKEDVECTOR_HPP +#define CXNA_COMMON_PACKEDVECTOR_HPP + +#include "vectors.hpp" +#include +#include "../default.hpp" + +namespace xna { + class IPackedVector { + virtual Vector4 ToVector4() const = 0; + virtual void PackFromVector4(Vector4 const& vector) = 0; + }; + + template + class IPackedVectorT { + virtual T PackedValue() const = 0; + virtual void PackedValue(T const& value) = 0; + }; + + struct PackUtils { + static Uint PackUnsigned(float bitmask, float value) { + return static_cast(ClampAndRound(value, 0.0f, bitmask)); + } + + static Uint PackSigned(Uint bitmask, float value) { + const auto max = static_cast(bitmask >> 1); + const auto min = -max - 1.0F; + + return static_cast(ClampAndRound(value, min, max)) & bitmask; + } + + static Uint PackUNorm(float bitmask, float value) { + value *= bitmask; + return static_cast(ClampAndRound(value, 0.0f, bitmask)); + } + + static constexpr float UnpackUNorm(Uint bitmask, Uint value) { + value &= bitmask; + return static_cast(value) / static_cast(bitmask); + } + + static Uint PackSNorm(Uint bitmask, float value) { + const auto max = static_cast(bitmask >> 1); + value *= max; + return static_cast(ClampAndRound(value, -max, max)) & bitmask; + } + + static constexpr float UnpackSNorm(Uint bitmask, Uint value) { + const auto num1 = (bitmask + 1U) >> 1; + + const auto ivalue = static_cast(value); + const auto inum1 = static_cast(num1); + const auto ibitmask = static_cast(bitmask); + + if ((ivalue & inum1) != 0) { + if ((ivalue & ibitmask) == inum1) + return -1.0f; + + value |= ~bitmask; + } + else + value &= bitmask; + + const auto num2 = static_cast(bitmask >> 1); + + return static_cast(value) / num2; + } + + static double ClampAndRound(float value, float min, float max) { + if (isnan(value)) + return 0.0; + + if (isinf(value)) + return value < 0 ? static_cast(min) : static_cast(max); + + if (value < min) + return static_cast(min); + + return value > max ? static_cast(max) : std::round(static_cast(value)); + } + }; +} + +#endif \ No newline at end of file diff --git a/framework/default.hpp b/framework/default.hpp index a61bea7..00c72d8 100644 --- a/framework/default.hpp +++ b/framework/default.hpp @@ -1,4 +1,4 @@ -#include "../types.hpp" -#include "../forward.hpp" -#include "../xnaerror.hpp" -#include "../enums.hpp" \ No newline at end of file +#include "types.hpp" +#include "forward.hpp" +#include "xnaerror.hpp" +#include "enums.hpp" \ No newline at end of file diff --git a/framework/enums.hpp b/framework/enums.hpp index 9a46d9b..f8c30bf 100644 --- a/framework/enums.hpp +++ b/framework/enums.hpp @@ -101,6 +101,22 @@ namespace xna { End, }; + enum class SpriteEffects { + None = 0, + FlipHorizontally = 1, + FlipVertically = 2, + Both = FlipHorizontally | FlipVertically + }; + + enum class SpriteSortMode + { + Deferred, + Immediate, + Texture, + BackToFront, + FrontToBack, + }; + enum class SurfaceFormat { Color = 0, Bgr565 = 1, @@ -144,6 +160,8 @@ namespace xna { MinPointMagLinearMipPoint, }; + + constexpr int SURFACE_FORMAT_COUNT = 19; } diff --git a/framework/forward.hpp b/framework/forward.hpp index 16fa320..7c45d06 100644 --- a/framework/forward.hpp +++ b/framework/forward.hpp @@ -115,6 +115,8 @@ namespace xna { using PSamplerState = std::shared_ptr; class Shader; using PShader = std::shared_ptr; + class SpriteBatch; + using PSpriteBatch = std::shared_ptr; class VertexBuffer; using PVertexBuffer = std::shared_ptr; class VertexInputLayout; diff --git a/framework/graphics/spritebatch.hpp b/framework/graphics/spritebatch.hpp new file mode 100644 index 0000000..1ca8fa4 --- /dev/null +++ b/framework/graphics/spritebatch.hpp @@ -0,0 +1,37 @@ +#ifndef XNA_GRAPHICS_SPRITEBATCH_HPP +#define XNA_GRAPHICS_SPRITEBATCH_HPP + +#include "../default.hpp" +#include "../common/matrix.hpp" + +namespace xna { + class ISpriteBatch { + public: + static constexpr Matrix _identity = Matrix::Identity(); + + virtual ~ISpriteBatch(){} + virtual void Begin( + SpriteSortMode sortMode = SpriteSortMode::Deferred, + BlendState* blendState = nullptr, + SamplerState* samplerState = nullptr, + //DepthStencilState + RasterizerState* rasterizerState = nullptr, + //Effect + Matrix const& transformMatrix = _identity + ) = 0; + virtual void End() = 0; + virtual void Draw(Texture2D& texture, Vector2 const& position, Color const& color) = 0; + virtual void Draw(Texture2D& texture, Vector2 const& position, Rectangle const * sourceRectangle, Color const& color) = 0; + virtual void Draw(Texture2D& texture, Vector2 const& position, Rectangle const* sourceRectangle, Color const& color, + float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth) = 0; + virtual void Draw(Texture2D& texture, Vector2 const& position, Rectangle const* sourceRectangle, Color const& color, + float rotation, Vector2 const& origin, Vector2 const& scale, SpriteEffects effects, float layerDepth) = 0; + virtual void Draw(Texture2D& texture, Rectangle const& destinationRectangle, Color const& color) = 0; + virtual void Draw(Texture2D& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color) = 0; + virtual void Draw(Texture2D& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color, + float rotation, Vector2 const& origin, SpriteEffects effects, float layerDepth) = 0; + virtual void Viewport(xna::Viewport const& value) = 0; + }; +} + +#endif \ No newline at end of file diff --git a/framework/platform/spritebatch-dx.cpp b/framework/platform/spritebatch-dx.cpp new file mode 100644 index 0000000..b8b924f --- /dev/null +++ b/framework/platform/spritebatch-dx.cpp @@ -0,0 +1,278 @@ +#include "spritebatch-dx.hpp" +#include "device-dx.hpp" +#include "blendstate-dx.hpp" +#include "samplerstate-dx.hpp" +#include "rasterizerstate-dx.hpp" +#include "../common/color.hpp" +#include "texture-dx.hpp" +#include "../common/vectors.hpp" +#include "../common/rectangle.hpp" +#include "../graphics/viewport.hpp" + +using DxSpriteBatch = DirectX::SpriteBatch; +using DxSpriteSortMode = DirectX::SpriteSortMode; +using DxMatrix = DirectX::FXMMATRIX; +using DxSpriteEffects = DirectX::SpriteEffects; +using DirectX::XMFLOAT2; +using DirectX::FXMVECTOR; +using DirectX::XMVECTORF32; +using DirectX::GXMVECTOR; + +namespace xna { + SpriteBatch::SpriteBatch(GraphicsDevice& device) { + _dxspriteBatch = New(device._context); + + Viewport(device.Viewport()); + } + + void SpriteBatch::Begin(SpriteSortMode sortMode, BlendState* blendState, SamplerState* samplerState, RasterizerState* rasterizerState, Matrix const& transformMatrix) { + + if (!_dxspriteBatch) + return; + + DxSpriteSortMode sort; + ConvertSpriteSort(sortMode, sort); + + 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); + + + _dxspriteBatch->Begin( + sort, + blendState ? blendState->_blendState : nullptr, + samplerState ? samplerState->_samplerState : nullptr, + nullptr, + rasterizerState ? rasterizerState->_rasterizerState : nullptr, + nullptr, + matrix + ); + } + + void SpriteBatch::End() { + if (!_dxspriteBatch) + return; + + _dxspriteBatch->End(); + } + + void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, Color const& color) { + if (!_dxspriteBatch) + return; + + if (!texture._textureView) + return; + + auto _position = XMFLOAT2(position.X, position.Y); + const auto v4 = color.ToVector4(); + XMVECTORF32 _color = { { { v4.X, v4.Y, v4.Z, v4.W } } }; + + _dxspriteBatch->Draw( + texture._textureView, + _position, + _color + ); + } + + void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, Rectangle const* sourceRectangle, Color const& color) { + if (!_dxspriteBatch) + return; + + if (!texture._textureView) + return; + + auto _position = XMFLOAT2(position.X, position.Y); + const auto v4 = color.ToVector4(); + XMVECTORF32 _color = { { { v4.X, v4.Y, v4.Z, v4.W } } }; + + RECT _sourceRect{}; + + if (sourceRectangle) { + _sourceRect.top = sourceRectangle->Y; + _sourceRect.left = sourceRectangle->X; + _sourceRect.right = sourceRectangle->X + sourceRectangle->Width; + _sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height; + }; + + _dxspriteBatch->Draw( + texture._textureView, + _position, + sourceRectangle ? &_sourceRect : nullptr, + _color); + } + + void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, Rectangle const* sourceRectangle, Color const& color, float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth) { + if (!_dxspriteBatch) + return; + + if (!texture._textureView) + return; + + auto _position = XMFLOAT2(position.X, position.Y); + auto _origin = XMFLOAT2(origin.X, origin.Y); + const auto v4 = color.ToVector4(); + XMVECTORF32 _color = { { { v4.X, v4.Y, v4.Z, v4.W } } }; + + RECT _sourceRect{}; + + if (sourceRectangle) { + _sourceRect.top = sourceRectangle->Y; + _sourceRect.left = sourceRectangle->X; + _sourceRect.right = sourceRectangle->X + sourceRectangle->Width; + _sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height; + }; + + DxSpriteEffects _effects = static_cast(effects); + + _dxspriteBatch->Draw( + texture._textureView, + _position, + sourceRectangle ? &_sourceRect : nullptr, + _color, + rotation, + _origin, + scale, + _effects, + layerDepth); + } + + void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, Rectangle const* sourceRectangle, Color const& color, float rotation, Vector2 const& origin, Vector2 const& scale, SpriteEffects effects, float layerDepth) { + if (!_dxspriteBatch) + return; + + if (!texture._textureView) + return; + + auto _position = XMFLOAT2(position.X, position.Y); + auto _origin = XMFLOAT2(origin.X, origin.Y); + const auto v4 = color.ToVector4(); + XMVECTORF32 _color = { { { v4.X, v4.Y, v4.Z, v4.W } } }; + + RECT _sourceRect{}; + + if (sourceRectangle) { + _sourceRect.top = sourceRectangle->Y; + _sourceRect.left = sourceRectangle->X; + _sourceRect.right = sourceRectangle->X + sourceRectangle->Width; + _sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height; + }; + + DxSpriteEffects _effects = static_cast(effects); + const XMFLOAT2 _scale = { scale.X, scale.Y }; + + _dxspriteBatch->Draw( + texture._textureView, + _position, + sourceRectangle ? &_sourceRect : nullptr, + _color, + rotation, + _origin, + _scale, + _effects, + layerDepth); + } + + void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, Color const& color) { + if (!_dxspriteBatch) + return; + + if (!texture._textureView) + return; + + RECT _destinationRect{}; + _destinationRect.left = destinationRectangle.X; + _destinationRect.top = destinationRectangle.Y; + _destinationRect.right = destinationRectangle.X + destinationRectangle.Width; + _destinationRect.bottom = destinationRectangle.Y + destinationRectangle.Height; + + const auto v4 = color.ToVector4(); + XMVECTORF32 _color = { { { v4.X, v4.Y, v4.Z, v4.W } } }; + + _dxspriteBatch->Draw(texture._textureView, _destinationRect, _color); + } + + void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color) { + if (!_dxspriteBatch) + return; + + if (!texture._textureView) + return; + + RECT _destinationRect{}; + _destinationRect.left = destinationRectangle.X; + _destinationRect.top = destinationRectangle.Y; + _destinationRect.right = destinationRectangle.X + destinationRectangle.Width; + _destinationRect.bottom = destinationRectangle.Y + destinationRectangle.Height; + + const auto v4 = color.ToVector4(); + XMVECTORF32 _color = { { { v4.X, v4.Y, v4.Z, v4.W } } }; + + RECT _sourceRect{}; + + if (sourceRectangle) { + _sourceRect.top = sourceRectangle->Y; + _sourceRect.left = sourceRectangle->X; + _sourceRect.right = sourceRectangle->X + sourceRectangle->Width; + _sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height; + }; + + _dxspriteBatch->Draw(texture._textureView, _destinationRect, sourceRectangle ? &_sourceRect : nullptr, _color); + } + + void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color, float rotation, Vector2 const& origin, SpriteEffects effects, float layerDepth) { + if (!_dxspriteBatch) + return; + + if (!texture._textureView) + return; + + RECT _destinationRect{}; + _destinationRect.left = destinationRectangle.X; + _destinationRect.top = destinationRectangle.Y; + _destinationRect.right = destinationRectangle.X + destinationRectangle.Width; + _destinationRect.bottom = destinationRectangle.Y + destinationRectangle.Height; + + const auto v4 = color.ToVector4(); + XMVECTORF32 _color = { { { v4.X, v4.Y, v4.Z, v4.W } } }; + + RECT _sourceRect{}; + + if (sourceRectangle) { + _sourceRect.top = sourceRectangle->Y; + _sourceRect.left = sourceRectangle->X; + _sourceRect.right = sourceRectangle->X + sourceRectangle->Width; + _sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height; + }; + + auto _origin = XMFLOAT2(origin.X, origin.Y); + DxSpriteEffects _effects = static_cast(effects); + + _dxspriteBatch->Draw( + texture._textureView, + _destinationRect, + sourceRectangle ? &_sourceRect : nullptr, + _color, + rotation, + _origin, + _effects, + layerDepth); + } + + void SpriteBatch::Viewport(xna::Viewport const& value) { + if (!_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; + + _dxspriteBatch->SetViewport(_view); + } +} diff --git a/framework/platform/spritebatch-dx.hpp b/framework/platform/spritebatch-dx.hpp new file mode 100644 index 0000000..44f170e --- /dev/null +++ b/framework/platform/spritebatch-dx.hpp @@ -0,0 +1,66 @@ +#ifndef XNA_PLATFORM_SPRITEBATCH_DX_HPP +#define XNA_PLATFORM_SPRITEBATCH_DX_HPP + +#include "../graphics/spritebatch.hpp" +#include "SpriteBatch.h" + +namespace xna { + class SpriteBatch : public ISpriteBatch { + public: + SpriteBatch(GraphicsDevice& device); + + virtual ~SpriteBatch() override {} + + virtual void Begin( + SpriteSortMode sortMode = SpriteSortMode::Deferred, + BlendState* blendState = nullptr, + SamplerState* samplerState = nullptr, + //DepthStencilState + RasterizerState* rasterizerState = nullptr, + //Effect + Matrix const& transformMatrix = _identity + ) override; + + virtual void End() override; + virtual void Draw(Texture2D& texture, Vector2 const& position, Color const& color) override; + virtual void Draw(Texture2D& texture, Vector2 const& position, Rectangle const * sourceRectangle, Color const& color) override; + virtual void Draw(Texture2D& texture, Vector2 const& position, Rectangle const* sourceRectangle, Color const& color, + float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth) override; + virtual void Draw(Texture2D& texture, Vector2 const& position, Rectangle const* sourceRectangle, Color const& color, + float rotation, Vector2 const& origin, Vector2 const& scale, SpriteEffects effects, float layerDepth) override; + virtual void Draw(Texture2D& texture, Rectangle const& destinationRectangle, Color const& color) override; + virtual void Draw(Texture2D& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color) override; + virtual void Draw(Texture2D& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color, + float rotation, Vector2 const& origin, SpriteEffects effects, float layerDepth) override; + virtual void Viewport(xna::Viewport const& value) override; + + public: + sptr _dxspriteBatch = nullptr; + + static constexpr void ConvertSpriteSort(SpriteSortMode value, DirectX::SpriteSortMode& target) { + switch (value) + { + case xna::SpriteSortMode::Deferred: + target = DirectX::SpriteSortMode_Deferred; + break; + case xna::SpriteSortMode::Immediate: + target = DirectX::SpriteSortMode_Immediate; + break; + case xna::SpriteSortMode::Texture: + target = DirectX::SpriteSortMode_Texture; + break; + case xna::SpriteSortMode::BackToFront: + target = DirectX::SpriteSortMode_BackToFront; + break; + case xna::SpriteSortMode::FrontToBack: + target = DirectX::SpriteSortMode_FrontToBack; + break; + default: + target = DirectX::SpriteSortMode_Deferred; + break; + } + } + }; +} + +#endif \ No newline at end of file diff --git a/framework/platform/texture-dx.cpp b/framework/platform/texture-dx.cpp index 996fef0..74470e1 100644 --- a/framework/platform/texture-dx.cpp +++ b/framework/platform/texture-dx.cpp @@ -5,21 +5,25 @@ namespace xna { Texture2D::Texture2D() { - } + } PTexture2D Texture2D::FromStream(GraphicsDevice& device, String const& fileName, xna_error_ptr_arg) { - ID3D11Resource* resource = nullptr; - //D3D11ShaderResourceView* view = nullptr; + auto texture2d = New(); + ID3D11Resource* resource = nullptr; auto wstr = StringToWString(fileName); HRESULT result = DirectX::CreateWICTextureFromFile( - device._device, device._context, wstr.c_str(), - &resource, nullptr, 0U); + device._device, + device._context, + wstr.c_str(), + &resource, + &texture2d->_textureView, + 0U); if (FAILED(result)) { - xna_error_apply(err, XnaErrorCode::STREAM_ERROR); + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); if (resource) { resource->Release(); @@ -28,12 +32,11 @@ namespace xna { return nullptr; } - - ID3D11Texture2D* txt2d = nullptr; - result = resource->QueryInterface(IID_ID3D11Texture2D, (void**)&txt2d); + + result = resource->QueryInterface(IID_ID3D11Texture2D, (void**)&texture2d->_texture2D); if (FAILED(result)) { - xna_error_apply(err, XnaErrorCode::BAD_CAST); + xna_error_apply(err, XnaErrorCode::FAILED_OPERATION); if (resource) { resource->Release(); @@ -43,8 +46,9 @@ namespace xna { return nullptr; } - auto texture2d = New(); - texture2d->_texture2D = txt2d; + D3D11_TEXTURE2D_DESC desc; + texture2d->_texture2D->GetDesc(&desc); + texture2d->_description = desc; resource->Release(); resource = nullptr; diff --git a/framework/platform/texture-dx.hpp b/framework/platform/texture-dx.hpp index 8f6873b..7270b9a 100644 --- a/framework/platform/texture-dx.hpp +++ b/framework/platform/texture-dx.hpp @@ -16,24 +16,28 @@ namespace xna { _texture2D->Release(); _texture2D = nullptr; } + + if (_textureView) { + _textureView->Release(); + _textureView = nullptr; + } } virtual constexpr Int Width() const override { - return _width; + return _description.Width; } virtual constexpr Int Height() const override { - return _height; + return _description.Height; } - static PTexture2D FromStream(GraphicsDevice& device, String const& fileName, xna_error_nullarg); + static PTexture2D FromStream(GraphicsDevice& device, String const& fileName, xna_error_nullarg); public: ID3D11Texture2D* _texture2D{nullptr}; - - private: - Uint _width{ 0 }; - Uint _height{ 0 }; + ID3D11ShaderResourceView* _textureView{ nullptr }; + D3D11_TEXTURE2D_DESC _description{}; + }; }