diff --git a/includes/xna-dx/implementations.hpp b/includes/xna-dx/implementations.hpp index a049b13..6070bab 100644 --- a/includes/xna-dx/implementations.hpp +++ b/includes/xna-dx/implementations.hpp @@ -54,15 +54,15 @@ namespace xna { UINT vSyncValue = 1; }; - struct SpriteFont::PlatformImplementation { - uptr dxSpriteFont{ nullptr }; + struct SpriteBatchImplementation { + std::shared_ptr SpriteBatch; + comptr InputLayout; + std::shared_ptr EffectBuffer; }; - struct SpriteBatch::PlatformImplementation { - sptr dxSpriteBatch = nullptr; - comptr dxInputLayout = nullptr; - sptr dxEffectBuffer = nullptr; - }; + struct SpriteFontImplementation { + std::unique_ptr SpriteFont; + }; struct GamePad::PlatformImplementation { uptr _dxGamePad = unew(); diff --git a/includes/xna/content/readers/graphics.hpp b/includes/xna/content/readers/graphics.hpp index 188d28c..3cec14e 100644 --- a/includes/xna/content/readers/graphics.hpp +++ b/includes/xna/content/readers/graphics.hpp @@ -42,6 +42,7 @@ namespace xna { } }; + using PSpriteFont = std::shared_ptr; class SpriteFontReader : public ContentTypeReaderT { public: SpriteFontReader() : ContentTypeReaderT(typeof()) { diff --git a/includes/xna/enumerations.hpp b/includes/xna/enumerations.hpp index 7d7d481..3cf975a 100644 --- a/includes/xna/enumerations.hpp +++ b/includes/xna/enumerations.hpp @@ -143,15 +143,7 @@ namespace xna { FlipVertically = 2, Both = FlipHorizontally | FlipVertically }; - - enum class SpriteSortMode - { - Deferred, - Immediate, - Texture, - BackToFront, - FrontToBack, - }; + enum class TextureAddressMode { Wrap, diff --git a/includes/xna/graphics/sprite.hpp b/includes/xna/graphics/sprite.hpp index 90a2964..b0aeafd 100644 --- a/includes/xna/graphics/sprite.hpp +++ b/includes/xna/graphics/sprite.hpp @@ -3,56 +3,82 @@ #include "../common/color.hpp" #include "../common/numerics.hpp" -#include "../default.hpp" #include "../graphics/gresource.hpp" +#include "../platform.hpp" +#include +#include +#include namespace xna { + //Defines sprite sort-rendering options. + enum class SpriteSortMode + { + //Sprites are not drawn until End is called. + //End will apply graphics device settings and draw all the sprites in one batch, in the same order calls to Draw were received. + //This mode allows Draw calls to two or more instances of SpriteBatch without introducing conflicting graphics device settings. + //SpriteBatch defaults to Deferred mode. + Deferred, + //Begin will apply new graphics device settings, and sprites will be drawn within each Draw call. + //In Immediate mode there can only be one active SpriteBatch instance without introducing conflicting device settings. + Immediate, + //Same as Deferred mode, except sprites are sorted by texture prior to drawing. + //This can improve performance when drawing non-overlapping sprites of uniform depth. + Texture, + //Same as Deferred mode, except sprites are sorted by depth in back-to-front order prior to drawing. + //This procedure is recommended when drawing transparent sprites of varying depths. + BackToFront, + //Same as Deferred mode, except sprites are sorted by depth in front-to-back order prior to drawing. + //This procedure is recommended when drawing opaque sprites of varying depths. + FrontToBack, + }; + + struct SpriteBatchImplementation; + //Enables a group of sprites to be drawn using the same settings. - class SpriteBatch : public GraphicsResource { + class SpriteBatch : public GraphicsResource, public PlatformImplementation { public: - SpriteBatch(sptr const& device); + SpriteBatch(std::shared_ptr const& device); //Begins a sprite batch operation. void Begin( std::optional sortMode, - uptr blendState, - uptr samplerState, - uptr depthStencil, - uptr rasterizerState, - uptr effect, - Matrix const& transformMatrix = Matrix::Identity() - ) { + std::unique_ptr blendState, + std::unique_ptr samplerState, + std::unique_ptr depthStencil, + std::unique_ptr rasterizerState, + std::unique_ptr effect, + Matrix const& transformMatrix = Matrix::Identity()) + { Begin( - !sortMode.has_value() ? SpriteSortMode::Deferred : sortMode.value(), + sortMode.has_value() ? sortMode.value() : SpriteSortMode::Deferred, blendState.get(), samplerState.get(), depthStencil.get(), rasterizerState.get(), effect.get(), - transformMatrix - ); + transformMatrix); } + //Begins a sprite batch operation. void Begin( std::optional sortMode, - sptr blendState, - sptr samplerState, - sptr depthStencil, - sptr rasterizerState, - sptr effect, - Matrix const& transformMatrix = Matrix::Identity() - ) { + std::shared_ptr blendState, + std::shared_ptr samplerState, + std::shared_ptr depthStencil, + std::shared_ptr rasterizerState, + std::shared_ptr effect, + Matrix const& transformMatrix = Matrix::Identity()) { Begin( - !sortMode.has_value() ? SpriteSortMode::Deferred : sortMode.value(), + sortMode.has_value() ? sortMode.value() : SpriteSortMode::Deferred, blendState.get(), samplerState.get(), depthStencil.get(), rasterizerState.get(), effect.get(), - transformMatrix - ); + transformMatrix); } + //Begins a sprite batch operation. void Begin( SpriteSortMode sortMode = SpriteSortMode::Deferred, BlendState* blendState = nullptr, @@ -70,39 +96,39 @@ namespace xna { // Draw - Adds a sprite to a batch of sprites to be rendered. // - 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(std::unique_ptr const& texture, Vector2 const& position, Color const& color) { Draw(*texture, position, color); } + void Draw(std::shared_ptr const& texture, Vector2 const& position, Color const& color) { Draw(*texture, position, color); } void Draw(Texture2D& texture, Vector2 const& position, 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(std::unique_ptr const& texture, Vector2 const& position, std::optional const& sourceRectangle, Color const& color) { Draw(*texture, position, sourceRectangle, color); } + void Draw(std::shared_ptr 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(uptr const& texture, Vector2 const& position, std::optional const& sourceRectangle, Color const& color, + void Draw(std::unique_ptr 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, + void Draw(std::shared_ptr 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(uptr const& texture, Vector2 const& position, std::optional const& sourceRectangle, Color const& color, + void Draw(std::unique_ptr 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, + void Draw(std::shared_ptr 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(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(std::unique_ptr const& texture, Rectangle const& destinationRectangle, Color const& color) { Draw(*texture, destinationRectangle, color); } + void Draw(std::shared_ptr const& texture, Rectangle const& destinationRectangle, Color const& color) { Draw(*texture, destinationRectangle, color); } void Draw(Texture2D& texture, Rectangle const& destinationRectangle, 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(std::unique_ptr const& texture, Rectangle const& destinationRectangle, std::optional const& sourceRectangle, Color const& color) { Draw(*texture, destinationRectangle, sourceRectangle, color); } + void Draw(std::shared_ptr 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(uptr const& texture, Rectangle const& destinationRectangle, std::optional const& sourceRectangle, Color const& color, + void Draw(std::unique_ptr 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, + void Draw(std::shared_ptr 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); @@ -111,57 +137,47 @@ namespace xna { // DrawString - Adds a string to a batch of sprites to be rendered. // - 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(std::unique_ptr const& spriteFont, std::string const& text, Vector2 const& position, Color const& color) { DrawString(*spriteFont, text, position, color); } + void DrawString(std::shared_ptr const& spriteFont, std::string const& text, Vector2 const& position, Color const& color) { DrawString(*spriteFont, text, position, color); } + void DrawString(SpriteFont& spriteFont, std::string const& text, Vector2 const& position, Color const& color); - void DrawString(uptr const& spriteFont, String const& text, Vector2 const& position, Color const& color, + void DrawString(std::unique_ptr const& spriteFont, std::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, + void DrawString(std::shared_ptr const& spriteFont, std::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(SpriteFont& spriteFont, String const& text, Vector2 const& position, Color const& color, + void DrawString(SpriteFont& spriteFont, std::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 impl = nullptr; }; + struct SpriteFontImplementation; + //Represents a font texture. - class SpriteFont { + class SpriteFont : public PlatformImplementation { public: SpriteFont( - sptr const& texture, + std::shared_ptr const& texture, std::vector const& glyphs, std::vector const& cropping, std::vector const& charMap, - Int lineSpacing, + int32_t lineSpacing, float spacing, std::vector const& kerning, std::optional const& defaultCharacter); // Returns the width and height of a string. - Vector2 MeasureString(String const& text, bool ignoreWhiteSpace = true); + Vector2 MeasureString(std::string const& text, bool ignoreWhiteSpace = true); // Returns the width and height of a string. - Vector2 MeasureString(WString const& text, bool ignoreWhiteSpace = true); + Vector2 MeasureString(std::wstring const& text, bool ignoreWhiteSpace = true); //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; + int32_t LineSpacing() const; //Gets or sets the vertical distance (in pixels) between the base lines of two consecutive lines of text - void LineSpacing(float value); - - public: - struct PlatformImplementation; - uptr impl = nullptr; + void LineSpacing(float value); }; - - using PSpriteFont = sptr; } #endif \ No newline at end of file diff --git a/sources/framework-dx/sprite.cpp b/sources/framework-dx/sprite.cpp index b29831d..859c60f 100644 --- a/sources/framework-dx/sprite.cpp +++ b/sources/framework-dx/sprite.cpp @@ -1,5 +1,4 @@ #include "xna-dx/framework.hpp" -#include using DxSpriteBatch = DirectX::SpriteBatch; using DxSpriteSortMode = DirectX::SpriteSortMode; @@ -53,8 +52,8 @@ namespace xna { dxGlyps[i] = g; } - impl = unew(); - impl->dxSpriteFont = unew( + Implementation = unew(); + Implementation->SpriteFont = unew( //ID3D11ShaderResourceView* texture texture->impl->dxShaderResource.Get(), //Glyph const* glyphs @@ -67,12 +66,12 @@ namespace xna { if (defaultCharacter.has_value()) { const auto defChar = static_cast(defaultCharacter.value()); - impl->dxSpriteFont->SetDefaultCharacter(defChar); + Implementation->SpriteFont->SetDefaultCharacter(defChar); } } Vector2 SpriteFont::MeasureString(String const& text, bool ignoreWhiteSpace) { - const auto size = impl->dxSpriteFont->MeasureString(text.c_str(), ignoreWhiteSpace); + const auto size = Implementation->SpriteFont->MeasureString(text.c_str(), ignoreWhiteSpace); Vector2 vec2{}; vec2.X = size.m128_f32[0]; vec2.Y = size.m128_f32[1]; @@ -81,7 +80,7 @@ namespace xna { } Vector2 SpriteFont::MeasureString(WString const& text, bool ignoreWhiteSpace){ - const auto size = impl->dxSpriteFont->MeasureString(text.c_str(), ignoreWhiteSpace); + const auto size = Implementation->SpriteFont->MeasureString(text.c_str(), ignoreWhiteSpace); Vector2 vec2{}; vec2.X = size.m128_f32[0]; vec2.Y = size.m128_f32[1]; @@ -90,30 +89,30 @@ namespace xna { } Char SpriteFont::DefaultCharacter() const { - const auto defChar = impl->dxSpriteFont->GetDefaultCharacter(); + const auto defChar = Implementation->SpriteFont->GetDefaultCharacter(); return static_cast(defChar); } void SpriteFont::DefaultCharacter(Char value) { const auto defChar = static_cast(value); - impl->dxSpriteFont->SetDefaultCharacter(defChar); + Implementation->SpriteFont->SetDefaultCharacter(defChar); } Int SpriteFont::LineSpacing() const { - const auto space = impl->dxSpriteFont->GetLineSpacing(); + const auto space = Implementation->SpriteFont->GetLineSpacing(); return static_cast(space); } void SpriteFont::LineSpacing(float value) { - impl->dxSpriteFont->SetLineSpacing(value); + Implementation->SpriteFont->SetLineSpacing(value); } SpriteBatch::SpriteBatch(sptr const& device) : GraphicsResource(device) { Exception::ThrowIfNull(device, nameof(device)); Exception::ThrowIfNull(device->Implementation->Context.Get(), nameof(device->Implementation->Context)); - impl = unew(); - impl->dxSpriteBatch = snew( + Implementation = unew(); + Implementation->SpriteBatch = snew( //ID3D11DeviceContext* deviceContext device->Implementation->Context.Get() ); @@ -128,12 +127,12 @@ namespace xna { if (effect) { bool dxEffectBufferChanged = false; - if (!impl->dxEffectBuffer || impl->dxEffectBuffer != effect->impl->dxEffect) { - impl->dxEffectBuffer = effect->impl->dxEffect; + if (!Implementation->EffectBuffer || Implementation->EffectBuffer != effect->impl->dxEffect) { + Implementation->EffectBuffer = effect->impl->dxEffect; dxEffectBufferChanged = true; } - if (!impl->dxInputLayout || dxEffectBufferChanged) { + if (!Implementation->InputLayout || dxEffectBufferChanged) { void const* shaderByteCode; size_t byteCodeLength; @@ -143,21 +142,21 @@ namespace xna { DirectX::VertexPositionColorTexture::InputElements, DirectX::VertexPositionColorTexture::InputElementCount, shaderByteCode, byteCodeLength, - impl->dxInputLayout.GetAddressOf()); + Implementation->InputLayout.GetAddressOf()); } auto& context = BaseGraphicsDevice->Implementation->Context; effectFunc = [=] { - impl->dxEffectBuffer->Apply(context.Get()); - context->IASetInputLayout(impl->dxInputLayout.Get()); + Implementation->EffectBuffer->Apply(context.Get()); + context->IASetInputLayout(Implementation->InputLayout.Get()); }; } auto _sortMode = DxHelpers::SpriteSortToDx(sortMode); auto _transformMatrix = DxHelpers::MatrixToDx(transformMatrix); - impl->dxSpriteBatch->Begin( + Implementation->SpriteBatch->Begin( _sortMode, blendState ? blendState->Implementation->BlendState.Get() : nullptr, samplerState ? samplerState->impl->_samplerState.Get() : nullptr, @@ -169,7 +168,7 @@ namespace xna { } void SpriteBatch::End() { - impl->dxSpriteBatch->End(); + Implementation->SpriteBatch->End(); } void SpriteBatch::Draw(Texture2D& texture, Vector2 const& position, Color const& color) { @@ -177,7 +176,7 @@ namespace xna { const auto v4 = color.ToVector4(); const auto _color = DxHelpers::VectorToDx(v4); - impl->dxSpriteBatch->Draw( + Implementation->SpriteBatch->Draw( texture.impl->dxShaderResource.Get(), _position, _color @@ -195,7 +194,7 @@ namespace xna { _sourceRect = DxHelpers::RectangleToDx(sourceRectangle.value()); }; - impl->dxSpriteBatch->Draw( + Implementation->SpriteBatch->Draw( texture.impl->dxShaderResource.Get(), _position, sourceRectangle ? &_sourceRect : nullptr, @@ -216,7 +215,7 @@ namespace xna { const DxSpriteEffects _effects = static_cast(effects); - impl->dxSpriteBatch->Draw( + Implementation->SpriteBatch->Draw( texture.impl->dxShaderResource.Get(), _position, sourceRectangle ? &_sourceRect : nullptr, @@ -243,7 +242,7 @@ namespace xna { const auto _effects = static_cast(effects); const XMFLOAT2 _scale = { scale.X, scale.Y }; - impl->dxSpriteBatch->Draw( + Implementation->SpriteBatch->Draw( texture.impl->dxShaderResource.Get(), _position, sourceRectangle ? &_sourceRect : nullptr, @@ -261,7 +260,7 @@ namespace xna { const auto v4 = color.ToVector4(); const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W }; - impl->dxSpriteBatch->Draw(texture.impl->dxShaderResource.Get(), _destinationRect, _color); + Implementation->SpriteBatch->Draw(texture.impl->dxShaderResource.Get(), _destinationRect, _color); } void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, std::optional const& sourceRectangle, Color const& color) { @@ -279,7 +278,7 @@ namespace xna { _sourceRect.bottom = sourceRectangle->Y + sourceRectangle->Height; }; - impl->dxSpriteBatch->Draw(texture.impl->dxShaderResource.Get(), _destinationRect, sourceRectangle ? &_sourceRect : nullptr, _color); + Implementation->SpriteBatch->Draw(texture.impl->dxShaderResource.Get(), _destinationRect, sourceRectangle ? &_sourceRect : nullptr, _color); } void SpriteBatch::Draw(Texture2D& texture, Rectangle const& destinationRectangle, std::optional const& sourceRectangle, Color const& color, float rotation, Vector2 const& origin, SpriteEffects effects, float layerDepth) { @@ -297,7 +296,7 @@ namespace xna { auto _origin = XMFLOAT2(origin.X, origin.Y); const auto _effects = static_cast(effects); - impl->dxSpriteBatch->Draw( + Implementation->SpriteBatch->Draw( texture.impl->dxShaderResource.Get(), _destinationRect, sourceRectangle ? &_sourceRect : nullptr, @@ -306,20 +305,15 @@ namespace xna { _origin, _effects, layerDepth); - } - - void SpriteBatch::Viewport(xna::Viewport const& value) { - const auto _view = DxHelpers::ViewportToDx(value); - impl->dxSpriteBatch->SetViewport(_view); - } + } void SpriteBatch::DrawString(SpriteFont& spriteFont, String const& text, Vector2 const& position, Color const& color) { const auto _position = XMFLOAT2(position.X, position.Y); const auto v4 = color.ToVector4(); const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W }; - spriteFont.impl->dxSpriteFont->DrawString( - impl->dxSpriteBatch.get(), + spriteFont.Implementation->SpriteFont->DrawString( + Implementation->SpriteBatch.get(), text.c_str(), _position, _color @@ -334,8 +328,8 @@ namespace xna { const XMVECTORF32 _color = { v4.X, v4.Y, v4.Z, v4.W }; const auto _effects = static_cast(effects); - spriteFont.impl->dxSpriteFont->DrawString( - impl->dxSpriteBatch.get(), + spriteFont.Implementation->SpriteFont->DrawString( + Implementation->SpriteBatch.get(), text.c_str(), _position, _color,