From d21d93eaf825d6a80f5e276ae931192299357d99 Mon Sep 17 00:00:00 2001 From: Danilo Date: Thu, 6 Jun 2024 14:18:16 -0300 Subject: [PATCH] =?UTF-8?q?Implementa=C3=A7=C3=B5es=20em=20Sprite?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- framework/platform-dx/sprite.cpp | 95 ++++++++++-------- inc/xna/common/numerics.hpp | 5 + inc/xna/graphics/sprite.hpp | 99 +++++++++---------- inc/xna/platform-dx/dx.hpp | 6 +- inc/xna/types.hpp | 3 +- .../02_PlatfformerStarterKit/animation.cpp | 2 +- samples/02_PlatfformerStarterKit/gem.cpp | 2 +- 7 files changed, 118 insertions(+), 94 deletions(-) diff --git a/framework/platform-dx/sprite.cpp b/framework/platform-dx/sprite.cpp index c05768a..3221aa7 100644 --- a/framework/platform-dx/sprite.cpp +++ b/framework/platform-dx/sprite.cpp @@ -28,26 +28,35 @@ namespace xna { Int lineSpacing, float spacing, std::vector const& kerning, - std::optional defaultCharacter) : - textureValue(texture), glyphData(glyphs), croppingData(cropping), - characterMap(charMap), lineSpacing(lineSpacing), spacing(spacing), - kerning(kerning), defaultCharacter(defaultCharacter) + std::optional const& defaultCharacter) { - if (!texture) + if (!texture || !texture->impl->dxShaderResource) throw std::invalid_argument("SpriteFont: texture is null."); + 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."); + std::vector dxGlyps(glyphs.size()); for (size_t i = 0; i < dxGlyps.size(); ++i) { DxGlyph g; - g.Subrect.left = glyphs[i].Left(); - g.Subrect.right = glyphs[i].Right(); - g.Subrect.top = glyphs[i].Top(); - g.Subrect.bottom = glyphs[i].Bottom(); + g.Subrect.left = static_cast(glyphs[i].Left()); + g.Subrect.right = static_cast(glyphs[i].Right()); + g.Subrect.top = static_cast(glyphs[i].Top()); + g.Subrect.bottom = static_cast(glyphs[i].Bottom()); g.Character = static_cast(charMap[i]); - g.XOffset = kerning[i].X; - g.YOffset = cropping[i].Y; - g.XAdvance = kerning[i].Z; + + if (!kerning.empty()) { + g.XOffset = kerning[i].X; + g.YOffset = static_cast(cropping[i].Y); + g.XAdvance = kerning[i].Z + spacing; + } + else { + g.XOffset = 0; + g.YOffset = 0; + g.XAdvance = spacing; + } + dxGlyps[i] = g; } @@ -67,14 +76,7 @@ namespace xna { const auto defChar = static_cast(defaultCharacter.value()); impl->_dxSpriteFont->SetDefaultCharacter(defChar); } - else { - impl->_dxSpriteFont->SetDefaultCharacter(charMap[0]); - } - } - - SpriteFont::~SpriteFont() { - impl = nullptr; - } + } Vector2 SpriteFont::MeasureString(String const& text, bool ignoreWhiteSpace) { @@ -102,22 +104,37 @@ namespace xna { return vec2; } - static constexpr void ConvertSpriteSort(SpriteSortMode value, DirectX::SpriteSortMode& target) { - target = static_cast(static_cast(value)); + Char SpriteFont::DefaultCharacter() const { + const auto defChar = impl->_dxSpriteFont->GetDefaultCharacter(); + return static_cast(defChar); + } + + void SpriteFont::DefaultCharacter(Char value) { + const auto defChar = static_cast(value); + impl->_dxSpriteFont->SetDefaultCharacter(defChar); } + Int SpriteFont::LineSpacing() const { + const auto space = impl->_dxSpriteFont->GetLineSpacing(); + return static_cast(space); + } + + void SpriteFont::LineSpacing(Int value) { + impl->_dxSpriteFont->SetLineSpacing(static_cast(value)); + } + SpriteBatch::SpriteBatch(GraphicsDevice& device) { if (!device.impl->_context) return; implementation = uNew(); - implementation->_dxspriteBatch = New(device.impl->_context); + implementation->_dxspriteBatch = New( + //ID3D11DeviceContext* deviceContext + device.impl->_context + ); Viewport(device.Viewport()); - } - - SpriteBatch::~SpriteBatch() { - } + } void SpriteBatch::Begin(SpriteSortMode sortMode, BlendState* blendState, SamplerState* samplerState, DepthStencilState* depthStencil, RasterizerState* rasterizerState, Matrix const& transformMatrix) { @@ -125,7 +142,7 @@ namespace xna { return; DxSpriteSortMode sort; - ConvertSpriteSort(sortMode, sort); + DxHelpers::ConvertSpriteSort(sortMode, sort); const auto& t = transformMatrix; DxMatrix matrix = DxMatrix( @@ -171,10 +188,10 @@ namespace xna { ); } - void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, Rectangle const* sourceRectangle, Color const& color) { + void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, std::optional const& sourceRectangle, Color const& color) { if (!implementation->_dxspriteBatch) return; - + if (!texture.impl->dxShaderResource) return; @@ -184,7 +201,7 @@ namespace xna { RECT _sourceRect{}; - if (sourceRectangle) { + if (sourceRectangle.has_value()) { _sourceRect.top = sourceRectangle->Y; _sourceRect.left = sourceRectangle->X; _sourceRect.right = sourceRectangle->X + sourceRectangle->Width; @@ -198,7 +215,7 @@ namespace xna { _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) { + void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, std::optional const& sourceRectangle, Color const& color, float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth) { if (!implementation->_dxspriteBatch) return; @@ -212,7 +229,7 @@ namespace xna { RECT _sourceRect{}; - if (sourceRectangle) { + if (sourceRectangle.has_value()) { _sourceRect.top = sourceRectangle->Y; _sourceRect.left = sourceRectangle->X; _sourceRect.right = sourceRectangle->X + sourceRectangle->Width; @@ -233,7 +250,7 @@ namespace xna { 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) { + void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, std::optional const& sourceRectangle, Color const& color, float rotation, Vector2 const& origin, Vector2 const& scale, SpriteEffects effects, float layerDepth) { if (!implementation->_dxspriteBatch) return; @@ -247,7 +264,7 @@ namespace xna { RECT _sourceRect{}; - if (sourceRectangle) { + if (sourceRectangle.has_value()) { _sourceRect.top = sourceRectangle->Y; _sourceRect.left = sourceRectangle->X; _sourceRect.right = sourceRectangle->X + sourceRectangle->Width; @@ -288,7 +305,7 @@ namespace xna { implementation->_dxspriteBatch->Draw(texture.impl->dxShaderResource, _destinationRect, _color); } - void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color) { + void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, std::optional const& sourceRectangle, Color const& color) { if (!implementation->_dxspriteBatch) return; @@ -306,7 +323,7 @@ namespace xna { RECT _sourceRect{}; - if (sourceRectangle) { + if (sourceRectangle.has_value()) { _sourceRect.top = sourceRectangle->Y; _sourceRect.left = sourceRectangle->X; _sourceRect.right = sourceRectangle->X + sourceRectangle->Width; @@ -316,7 +333,7 @@ namespace xna { implementation->_dxspriteBatch->Draw(texture.impl->dxShaderResource, _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) { + void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, std::optional const& sourceRectangle, Color const& color, float rotation, Vector2 const& origin, SpriteEffects effects, float layerDepth) { if (!implementation->_dxspriteBatch) return; @@ -334,7 +351,7 @@ namespace xna { RECT _sourceRect{}; - if (sourceRectangle) { + if (sourceRectangle.has_value()) { _sourceRect.top = sourceRectangle->Y; _sourceRect.left = sourceRectangle->X; _sourceRect.right = sourceRectangle->X + sourceRectangle->Width; diff --git a/inc/xna/common/numerics.hpp b/inc/xna/common/numerics.hpp index 8af7812..bb36aa5 100644 --- a/inc/xna/common/numerics.hpp +++ b/inc/xna/common/numerics.hpp @@ -3,6 +3,7 @@ #include #include "../default.hpp" +#include namespace xna { struct Point { @@ -34,6 +35,10 @@ namespace xna { return Height == other.Height && Width == other.Width && X == other.X && Y == other.Y; } + constexpr operator std::optional() const { + return std::make_optional(X, Y, Width, Height); + } + constexpr Int Left() const { return X; } constexpr Int Right() const { return X + Width; } constexpr Int Top() const { return Y; } diff --git a/inc/xna/graphics/sprite.hpp b/inc/xna/graphics/sprite.hpp index 039733b..a719a32 100644 --- a/inc/xna/graphics/sprite.hpp +++ b/inc/xna/graphics/sprite.hpp @@ -10,7 +10,6 @@ namespace xna { class SpriteBatch { public: SpriteBatch(GraphicsDevice& device); - ~SpriteBatch(); void Begin( SpriteSortMode sortMode = SpriteSortMode::Deferred, BlendState* blendState = nullptr, @@ -21,66 +20,63 @@ namespace xna { Matrix const& transformMatrix = Matrix::Identity() ); void End(); - void Draw(sptr const& texture, Vector2 const& position, Color const& color) { - Draw(*texture, position, color); - } + + void Draw(uptr const& texture, Vector2 const& position, Color const& color) { Draw(*texture, position, color); } + void Draw(sptr const& texture, Vector2 const& position, Color const& color) { Draw(*texture, position, color); } void Draw(Texture2D& texture, Vector2 const& position, Color const& color); - void Draw(sptr const& texture, Vector2 const& position, Rectangle const* sourceRectangle, Color const& color) { - Draw(*texture, position, sourceRectangle, color); - } - void Draw(Texture2D& texture, Vector2 const& position, Rectangle const* sourceRectangle, Color const& color); + void Draw(uptr const& texture, Vector2 const& position, std::optional const& sourceRectangle, Color const& color) { Draw(*texture, position, sourceRectangle, color); } + void Draw(sptr const& texture, Vector2 const& position, std::optional const& sourceRectangle, Color const& color) { Draw(*texture, position, sourceRectangle, color); } + void Draw(Texture2D& texture, Vector2 const& position, std::optional const& sourceRectangle, Color const& color); - void Draw(sptr const& texture, Vector2 const& position, Rectangle const* sourceRectangle, Color const& color, - float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth) { - Draw(*texture, position, sourceRectangle, color, rotation, origin, scale, effects, layerDepth); - } - void Draw(Texture2D& texture, Vector2 const& position, Rectangle const* sourceRectangle, Color const& color, + void Draw(uptr const& texture, Vector2 const& position, std::optional const& sourceRectangle, Color const& color, + float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth) { Draw(*texture, position, sourceRectangle, color, rotation, origin, scale, effects, layerDepth); } + void Draw(sptr const& texture, Vector2 const& position, std::optional const& sourceRectangle, Color const& color, + float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth) { Draw(*texture, position, sourceRectangle, color, rotation, origin, scale, effects, layerDepth); } + void Draw(Texture2D& texture, Vector2 const& position, std::optional const& sourceRectangle, Color const& color, float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth); - void Draw(sptr const& texture, Vector2 const& position, Rectangle const* sourceRectangle, Color const& color, - float rotation, Vector2 const& origin, Vector2 const& scale, SpriteEffects effects, float layerDepth) { - Draw(*texture, position, sourceRectangle, color, rotation, origin, scale, effects, layerDepth); - } - void Draw(Texture2D& texture, Vector2 const& position, Rectangle const* sourceRectangle, Color const& color, + void Draw(uptr const& texture, Vector2 const& position, std::optional const& sourceRectangle, Color const& color, + float rotation, Vector2 const& origin, Vector2 const& scale, SpriteEffects effects, float layerDepth) { Draw(*texture, position, sourceRectangle, color, rotation, origin, scale, effects, layerDepth); } + void Draw(sptr const& texture, Vector2 const& position, std::optional const& sourceRectangle, Color const& color, + float rotation, Vector2 const& origin, Vector2 const& scale, SpriteEffects effects, float layerDepth) { Draw(*texture, position, sourceRectangle, color, rotation, origin, scale, effects, layerDepth); } + void Draw(Texture2D& texture, Vector2 const& position, std::optional const& sourceRectangle, Color const& color, float rotation, Vector2 const& origin, Vector2 const& scale, SpriteEffects effects, float layerDepth); - void Draw(sptr const& texture, Rectangle const& destinationRectangle, Color const& color) { - Draw(*texture, destinationRectangle, color); - } + void Draw(uptr const& texture, Rectangle const& destinationRectangle, Color const& color) { Draw(*texture, destinationRectangle, color); } + void Draw(sptr const& texture, Rectangle const& destinationRectangle, Color const& color) { Draw(*texture, destinationRectangle, color); } void Draw(Texture2D& texture, Rectangle const& destinationRectangle, Color const& color); - void Draw(sptr const& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color) { - Draw(*texture, destinationRectangle, sourceRectangle, color); - } - void Draw(Texture2D& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color); + void Draw(uptr const& texture, Rectangle const& destinationRectangle, std::optional const& sourceRectangle, Color const& color) { Draw(*texture, destinationRectangle, sourceRectangle, color); } + void Draw(sptr const& texture, Rectangle const& destinationRectangle, std::optional const& sourceRectangle, Color const& color) { Draw(*texture, destinationRectangle, sourceRectangle, color); } + void Draw(Texture2D& texture, Rectangle const& destinationRectangle, std::optional const& sourceRectangle, Color const& color); - void Draw(sptr const& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color, - float rotation, Vector2 const& origin, SpriteEffects effects, float layerDepth) { - Draw(*texture, destinationRectangle, sourceRectangle, color, rotation, origin, effects, layerDepth); - } - void Draw(Texture2D& texture, Rectangle const& destinationRectangle, Rectangle const* sourceRectangle, Color const& color, - float rotation, Vector2 const& origin, SpriteEffects effects, float layerDepth); + void Draw(uptr const& texture, Rectangle const& destinationRectangle, std::optional const& sourceRectangle, Color const& color, + float rotation, Vector2 const& origin, SpriteEffects effects, float layerDepth) { Draw(*texture, destinationRectangle, sourceRectangle, color, rotation, origin, effects, layerDepth); } + void Draw(sptr const& texture, Rectangle const& destinationRectangle, std::optional const& sourceRectangle, Color const& color, + float rotation, Vector2 const& origin, SpriteEffects effects, float layerDepth) { Draw(*texture, destinationRectangle, sourceRectangle, color, rotation, origin, effects, layerDepth); } + void Draw(Texture2D& texture, Rectangle const& destinationRectangle, std::optional const& sourceRectangle, Color const& color, + float rotation, Vector2 const& origin, SpriteEffects effects, float layerDepth); - void Viewport(xna::Viewport const& value); - - void DrawString(sptr const& spriteFont, String const& text, Vector2 const& position, Color const& color) { - DrawString(*spriteFont, text, position, color); - } + void DrawString(uptr const& spriteFont, String const& text, Vector2 const& position, Color const& color) { DrawString(*spriteFont, text, position, color); } + void DrawString(sptr const& spriteFont, String const& text, Vector2 const& position, Color const& color) { DrawString(*spriteFont, text, position, color); } void DrawString(SpriteFont& spriteFont, String const& text, Vector2 const& position, Color const& color); + void DrawString(uptr const& spriteFont, String const& text, Vector2 const& position, Color const& color, + float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth) { DrawString(*spriteFont, text, position, color, rotation, origin, scale, effects, layerDepth); } void DrawString(sptr const& spriteFont, String const& text, Vector2 const& position, Color const& color, - float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth) { - DrawString(*spriteFont, text, position, color, rotation, origin, scale, effects, layerDepth); - } + float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth) { DrawString(*spriteFont, text, position, color, rotation, origin, scale, effects, layerDepth); } void DrawString(SpriteFont& spriteFont, String const& text, Vector2 const& position, Color const& color, float rotation, Vector2 const& origin, float scale, SpriteEffects effects, float layerDepth); + void Viewport(xna::Viewport const& value); + public: struct PlatformImplementation; uptr implementation = nullptr; }; + //Represents a font texture. class SpriteFont { public: SpriteFont( @@ -91,20 +87,21 @@ namespace xna { Int lineSpacing, float spacing, std::vector const& kerning, - std::optional defaultCharacter); - ~SpriteFont(); + std::optional const& defaultCharacter); + + // Returns the width and height of a string. Vector2 MeasureString(String const& text, bool ignoreWhiteSpace = true); - Vector2 MeasureString(WString const& text, bool ignoreWhiteSpace = true); + // Returns the width and height of a string. + Vector2 MeasureString(WString const& text, bool ignoreWhiteSpace = true); - private: - sptr textureValue = nullptr; - std::vector glyphData; - std::vector croppingData; - std::vector characterMap; - Int lineSpacing{0}; - float spacing{0}; - std::vector kerning; - std::optional defaultCharacter; + //Gets or sets the default character for the font. + Char DefaultCharacter() const; + //Gets or sets the default character for the font. + void DefaultCharacter(Char value); + //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); public: struct PlatformImplementation; diff --git a/inc/xna/platform-dx/dx.hpp b/inc/xna/platform-dx/dx.hpp index 2555106..0eb4db6 100644 --- a/inc/xna/platform-dx/dx.hpp +++ b/inc/xna/platform-dx/dx.hpp @@ -92,6 +92,10 @@ namespace xna { //==============================================// struct DxHelpers { + static constexpr void ConvertSpriteSort(SpriteSortMode value, DirectX::SpriteSortMode& target) { + target = static_cast(static_cast(value)); + } + static constexpr DXGI_FORMAT ConvertSurfaceToDXGIFORMAT(SurfaceFormat format) { switch (format) @@ -446,7 +450,7 @@ namespace xna { //==============================================// struct SpriteFont::PlatformImplementation { - sptr _dxSpriteFont = nullptr; + uptr _dxSpriteFont{ nullptr }; }; struct SpriteBatch::PlatformImplementation { diff --git a/inc/xna/types.hpp b/inc/xna/types.hpp index b58a932..f159402 100644 --- a/inc/xna/types.hpp +++ b/inc/xna/types.hpp @@ -8,6 +8,7 @@ #include #include #include +#include namespace xna { using Sbyte = int8_t; @@ -48,7 +49,7 @@ namespace xna { // using String = std::string; - using WString = std::wstring; + using WString = std::wstring; template using sptr = std::shared_ptr; diff --git a/samples/02_PlatfformerStarterKit/animation.cpp b/samples/02_PlatfformerStarterKit/animation.cpp index 350e1dc..bea1bc9 100644 --- a/samples/02_PlatfformerStarterKit/animation.cpp +++ b/samples/02_PlatfformerStarterKit/animation.cpp @@ -34,6 +34,6 @@ namespace PlatformerStarterKit { const auto source = xna::Rectangle(frameIndex * animation->Texture()->Height(), 0, animation->Texture()->Height(), animation->Texture()->Height()); // Draw the current frame. - spriteBatch.Draw(animation->Texture(), position, &source, xna::Colors::White, 0.0f, Origin(), 1.0f, spriteEffects, 0.0f); + spriteBatch.Draw(animation->Texture(), position, source, xna::Colors::White, 0.0f, Origin(), 1.0f, spriteEffects, 0.0f); } } \ No newline at end of file diff --git a/samples/02_PlatfformerStarterKit/gem.cpp b/samples/02_PlatfformerStarterKit/gem.cpp index 8c78095..26fde9b 100644 --- a/samples/02_PlatfformerStarterKit/gem.cpp +++ b/samples/02_PlatfformerStarterKit/gem.cpp @@ -34,6 +34,6 @@ namespace PlatformerStarterKit { void Gem::Draw(xna::GameTime const& gameTime, xna::SpriteBatch& spriteBatch) { - spriteBatch.Draw(texture, Position(), nullptr, Color, 0.0f, origin, 1.0f, xna::SpriteEffects::None, 0.0f); + spriteBatch.Draw(texture, Position(), std::nullopt, Color, 0.0f, origin, 1.0f, xna::SpriteEffects::None, 0.0f); } } \ No newline at end of file