Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

AnimatedTexture

Chuck Walbourn edited this page Apr 26, 2022 · 8 revisions

This is an example of a C++ port of the C# XNA Game Studio sample class for drawing an animated 2D sprite using SpriteBatch. The sprite animation is assumed to be laid out horizontally.

Related tutorial: More tricks with sprites

AnimatedTexture.h

class AnimatedTexture
{
public:
    AnimatedTexture()
    {
        ...
    }

    AnimatedTexture( const DirectX::XMFLOAT2& origin, float rotation, float scale,
        float depth )
    {
        ...
    }

    void Load( ID3D11ShaderResourceView* texture, int frameCount, int framesPerSecond )
    {
        if ( frameCount < 0 || framesPerSecond <= 0 )
            throw std::invalid_argument( "AnimatedTexture" );

        mPaused = false;
        mFrameCount = frameCount;
        mTimePerFrame = 1.f / float(framesPerSecond);
        mTotalElapsed = 0.f;
        mTexture = texture;

        if ( texture )
        {
            Microsoft::WRL::ComPtr<ID3D11Resource> resource;
            texture->GetResource( resource.GetAddressOf() );

            D3D11_RESOURCE_DIMENSION dim;
            resource->GetType( &dim );

            if ( dim != D3D11_RESOURCE_DIMENSION_TEXTURE2D )
                throw std::exception( "AnimatedTexture expects a Texture2D" );

            Microsoft::WRL::ComPtr<ID3D11Texture2D> tex2D;
            resource.As( &tex2D );

            D3D11_TEXTURE2D_DESC desc;
            tex2D->GetDesc( &desc );

            mTextureWidth = int( desc.Width );
            mTextureHeight = int( desc.Height );
        }
    }

    void Update( float elapsed )
    {
        if ( mPaused )
            return;

        mTotalElapsed += elapsed;

        if ( mTotalElapsed > mTimePerFrame )
        {
            ++mFrame;
            mFrame = mFrame % mFrameCount;
            mTotalElapsed -= mTimePerFrame;
        }
    }

    void Draw( DirectX::SpriteBatch* batch, const DirectX::XMFLOAT2& screenPos ) const
    {
        Draw( batch, mFrame, screenPos );
    }

    void Draw( DirectX::SpriteBatch* batch, int frame,
        const DirectX::XMFLOAT2& screenPos ) const
    {
        int frameWidth = mTextureWidth / mFrameCount;

        RECT sourceRect;
        sourceRect.left = frameWidth * frame;
        sourceRect.top = 0;
        sourceRect.right = sourceRect.left + frameWidth;
        sourceRect.bottom = mTextureHeight;

        batch->Draw( mTexture.Get(), screenPos, &sourceRect, DirectX::Colors::White,
                     mRotation, mOrigin, mScale, DirectX::SpriteEffects_None, mDepth );
    }

    void Reset()
    {
        mFrame = 0;
        mTotalElapsed = 0.f;
    }

    void Stop()
    {
        mPaused = true;
        mFrame = 0;
        mTotalElapsed = 0.f;
    }

    void Play() { mPaused = false; }
    void Paused() { mPaused = true; }

    bool IsPaused() const { return mPaused; }

private:
    bool                                                mPaused;
    int                                                 mFrame;
    int                                                 mFrameCount;
    int                                                 mTextureWidth;
    int                                                 mTextureHeight;
    float                                               mTimePerFrame;
    float                                               mTotalElapsed;
    float                                               mDepth;
    float                                               mRotation;
    DirectX::XMFLOAT2                                   mOrigin;
    DirectX::XMFLOAT2                                   mScale;
    Microsoft::WRL::ComPtr<ID3D11ShaderResourceView>    mTexture;
};

Example

This example uses a sprite sheet that has 4 frames of animation (shipanimated.dds)

Ship Animated

#include "DDSTextureLoader.h"
#include "SpriteBatch.h"
#include "AnimatedTexture.h"

Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> ship;
std::unique_ptr<DirectX::SpriteBatch> spriteBatch;
std::unique_ptr<AnimatedTexture> sprite;

// Create a texture using our sprite sheet
hr = CreateDDSTextureFromFile( device, L"shipanimated.dds", nullptr,
    ship.GetAddressOf() );
DX::ThrowIfFailed(hr);

...

// Create a sprite batch for drawing
spriteBatch = std::make_unique<SpriteBatch>( context );

// Create an AnimatedTexture helper class instance and set it to use our texture
// which is assumed to have 4 frames of animation with a FPS of 2 seconds
sprite = std::make_unique<AnimatedTexture>( XMFLOAT2(0,0), 0.f, 2.f, 0.5f );
sprite->Load( ship.Get(), 4, 2 );

...

// Update the sprite sheet animation based on current time
sprite->Update( timeDelta );

...

// Render the sprite using sprite batch
spriteBatch->Begin();
// TODO - background draw here

sprite->Draw( spriteBatch.get(), screenPos );

// TODO - More sprites or text here
spriteBatch->End();

For Use

  • Universal Windows Platform apps
  • Windows desktop apps
  • Windows 11
  • Windows 10
  • Windows 8.1
  • Xbox One

Architecture

  • x86
  • x64
  • ARM64

For Development

  • Visual Studio 2022
  • Visual Studio 2019 (16.11)
  • clang/LLVM v12 - v20
  • MinGW 12.2, 13.2
  • CMake 3.21

Related Projects

DirectX Tool Kit for DirectX 12

DirectXMesh

DirectXTex

DirectXMath

Win2D

Tools

Test Suite

Model Viewer

Content Exporter

DxCapsViewer

Clone this wiki locally

Morty Proxy This is a proxified and sanitized view of the page, visit original site.