Quantcast
Channel: directxtk Wiki Rss Feed
Viewing all articles
Browse latest Browse all 874

Updated Wiki: SpriteSheet

$
0
0
This is an example of a C++ port of the C# MonoGame sprite loader and renderer for use sprite sheets created by the CodeAndWeb tool "TexturePacker" using the MonoGame project settings.

https://www.codeandweb.com/texturepacker/monogame

You can easily this code to work with other sprite sheet creation tools by modifying the metadata reading code in Load.

SpriteSheet.h
class SpriteSheet
{
public:
    struct SpriteFrame
    {
        RECT                sourceRect;
        DirectX::XMFLOAT2   size;
        DirectX::XMFLOAT2   origin;
        bool                rotated;
    };

    void Load( ID3D11ShaderResourceView* texture, constwchar_t* szFileName )
    {
        mSprites.clear();

        mTexture = texture;

        if (szFileName)
        {
            //// This code parses the 'MonoGame' project txt file that is produced by// CodeAndWeb's TexturePacker.// https://www.codeandweb.com/texturepacker//// You can modify it to match whatever sprite-sheet tool you are using//

            std::wifstream inFile( szFileName );
            if( !inFile )
                throw std::exception( "SpriteSheet failed to load .txt data" );

            wchar_t strLine[1024];
            for(;;)
            {
                inFile >> strLine;
                if( !inFile )
                    break;

                if( 0 == wcscmp( strLine, L"#" ) )
                {
                    // Comment
                }
                else
                {
                    staticconstwchar_t* delim = L";\n";

                    wchar_t* context = nullptr;
                    wchar_t* name = wcstok_s(strLine, delim, &context);
                    if ( !name || !*name )
                        throw std::exception();

                    if ( mSprites.find( name ) != mSprites.cend() )
                        throw std::exception();

                    wchar_t* str = wcstok_s(nullptr, delim, &context);
                    if ( !str )
                        throw std::exception();

                    SpriteFrame frame;
                    frame.rotated = (_wtoi(str) == 1);

                    str = wcstok_s(nullptr, delim, &context);
                    if ( !str )
                        throw std::exception();
                    frame.sourceRect.left = _wtol(str);

                    str = wcstok_s(nullptr, delim, &context);
                    if ( !str )
                        throw std::exception();
                    frame.sourceRect.top = _wtol(str);

                    str = wcstok_s(nullptr, delim, &context);
                    if ( !str )
                        throw std::exception();
                    LONG dx = _wtol(str);
                    frame.sourceRect.right = frame.sourceRect.left + dx;

                    str = wcstok_s(nullptr, delim, &context);
                    if ( !str )
                        throw std::exception();
                    LONG dy = + _wtol(str);
                    frame.sourceRect.bottom = frame.sourceRect.top + dy;

                    str = wcstok_s(nullptr, delim, &context);
                    if ( !str )
                        throw std::exception();
                    frame.size.x = static_cast<float>( _wtof(str) );

                    str = wcstok_s(nullptr, delim, &context);
                    if ( !str )
                        throw std::exception();
                    frame.size.y = static_cast<float>( _wtof(str) );

                    str = wcstok_s(nullptr, delim, &context);
                    if ( !str )
                        throw std::exception();
                    float pivotX = static_cast<float>( _wtof(str) );

                    str = wcstok_s(nullptr, delim, &context);
                    if ( !str )
                        throw std::exception();
                    float pivotY = static_cast<float>( _wtof(str) );

                    if (frame.rotated)
                    {
                        frame.origin.x = dx * (1.f - pivotY);
                        frame.origin.y = dy * pivotX;
                    }
                    else
                    {
                        frame.origin.x = dx * pivotX;
                        frame.origin.y = dy * pivotY;
                    }

                    mSprites.insert( std::pair<std::wstring,SpriteFrame>(
                        std::wstring(name), frame) );
                }

                inFile.ignore( 1000, '\n' );
            }
        }
    }

    const SpriteFrame* Find(constwchar_t* name) const
    {
        auto it = mSprites.find(name);
        if (it == mSprites.cend())
            returnnullptr;

        return&it->second;
    }

    void XM_CALLCONV Draw(DirectX::SpriteBatch* batch, const SpriteFrame& frame,
        DirectX::XMFLOAT2 const& position,
        DirectX::FXMVECTOR color = DirectX::Colors::White, float rotation = 0,
        float scale = 1,
        DirectX::SpriteEffects effects = DirectX::SpriteEffects_None,
        float layerDepth = 0) const
    {
        assert(batch != 0);
        usingnamespace DirectX;

        if (frame.rotated)
        {
            rotation -= XM_PIDIV2;
            switch(effects)
            {
            case SpriteEffects_FlipHorizontally:    effects = SpriteEffects_FlipVertically; break;
            case SpriteEffects_FlipVertically:      effects = SpriteEffects_FlipHorizontally; break;
            }
        }

        XMFLOAT2 origin = frame.origin;
        switch (effects)
        {
        case SpriteEffects_FlipHorizontally:    origin.x = frame.sourceRect.right - frame.sourceRect.left - origin.x;
        case SpriteEffects_FlipVertically:      origin.y = frame.sourceRect.bottom - frame.sourceRect.top - origin.y;
        }

        batch->Draw(mTexture.Get(), position, &frame.sourceRect, color, rotation, origin, scale, effects, layerDepth );
    }

    void XM_CALLCONV Draw(DirectX::SpriteBatch* batch, const SpriteFrame& frame,
        DirectX::XMFLOAT2 const& position,
        DirectX::FXMVECTOR color, float rotation, DirectX::XMFLOAT2 const& scale,
        DirectX::SpriteEffects effects = DirectX::SpriteEffects_None,
        float layerDepth = 0) const;

    // Draw overloads specifying position and scale via the first two components of an XMVECTOR.void XM_CALLCONV Draw(DirectX::SpriteBatch* batch, const SpriteFrame& frame,
        DirectX::FXMVECTOR position,
        DirectX::FXMVECTOR color = DirectX::Colors::White, float rotation = 0,
        float scale = 1,
        DirectX::SpriteEffects effects = DirectX::SpriteEffects_None,
        float layerDepth = 0) const;

    void XM_CALLCONV Draw(DirectX::SpriteBatch* batch, const SpriteFrame& frame,
        DirectX::FXMVECTOR position,
        DirectX::FXMVECTOR color, float rotation, DirectX::GXMVECTOR scale,
        DirectX::SpriteEffects effects = DirectX::SpriteEffects_None,
        float layerDepth = 0) const;

    // Draw overloads specifying position as a RECT.void XM_CALLCONV Draw(DirectX::SpriteBatch* batch, const SpriteFrame& frame,
        RECT const& destinationRectangle,
        DirectX::FXMVECTOR color = DirectX::Colors::White, float rotation = 0,
        DirectX::SpriteEffects effects = DirectX::SpriteEffects_None,
        float layerDepth = 0) const;

private:
    Microsoft::WRL::ComPtr<ID3D11ShaderResourceView>    mTexture;
    std::map<std::wstring, SpriteFrame>                 mSprites;
};

Viewing all articles
Browse latest Browse all 874

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>