SpriteRenderer
This commit is contained in:
@ -19,8 +19,9 @@ set(SRC_FILES
|
|||||||
"Src/Imp/CPP/Renderer/GPUResourceManager.cpp"
|
"Src/Imp/CPP/Renderer/GPUResourceManager.cpp"
|
||||||
|
|
||||||
"Src/Imp/CPP/Nodes/Node2D.cpp"
|
"Src/Imp/CPP/Nodes/Node2D.cpp"
|
||||||
"Src/Imp/CPP/Nodes/TextureNode.cpp"
|
|
||||||
"Src/Imp/CPP/Nodes/CameraNode.cpp"
|
"Src/Imp/CPP/Nodes/CameraNode.cpp"
|
||||||
|
"Src/Imp/CPP/Nodes/SpriteNode.cpp"
|
||||||
|
"Src/Imp/CPP/Nodes/TextureNode.cpp"
|
||||||
|
|
||||||
"Src/Imp/CPP/Components/CameraComponent.cpp"
|
"Src/Imp/CPP/Components/CameraComponent.cpp"
|
||||||
"Src/Imp/CPP/Components/PhysicsComponent.cpp"
|
"Src/Imp/CPP/Components/PhysicsComponent.cpp"
|
||||||
|
|||||||
@ -0,0 +1,132 @@
|
|||||||
|
// IAEngine: 2D Game Engine by IA
|
||||||
|
// Copyright (C) 2025 IASoft (PVT) LTD (oss@iasoft.dev)
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <IAEngine/Engine.hpp>
|
||||||
|
|
||||||
|
namespace ia::iae
|
||||||
|
{
|
||||||
|
SpriteComponent::SpriteComponent(IN Node2D *node) : TextureComponent(node)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID SpriteComponent::Draw()
|
||||||
|
{
|
||||||
|
const auto &animFrame = m_currentAnimationState;
|
||||||
|
PositionOffset() = animFrame.Position;
|
||||||
|
ScaleOffset() = animFrame.Scale;
|
||||||
|
RotationOffset() = animFrame.Rotation;
|
||||||
|
ColorOverlay() = animFrame.ColorOverlay;
|
||||||
|
SetTexture(animFrame.Texture);
|
||||||
|
TextureComponent::Draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID SpriteComponent::DebugDraw()
|
||||||
|
{
|
||||||
|
TextureComponent::DebugDraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID SpriteComponent::Update()
|
||||||
|
{
|
||||||
|
TextureComponent::Update();
|
||||||
|
|
||||||
|
UpdateAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID SpriteComponent::FixedUpdate()
|
||||||
|
{
|
||||||
|
TextureComponent::FixedUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
Handle SpriteComponent::AddAnimation(IN CONST Animation &animation)
|
||||||
|
{
|
||||||
|
if (animation.Keys.empty())
|
||||||
|
return INVALID_HANDLE;
|
||||||
|
m_animations.pushBack(animation);
|
||||||
|
if(m_animations.size() == 1)
|
||||||
|
ForceSetActiveAnimation(0);
|
||||||
|
return m_animations.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID SpriteComponent::SetActiveAnimation(IN Handle animation)
|
||||||
|
{
|
||||||
|
if (animation == m_activeAnimationHandle)
|
||||||
|
return;
|
||||||
|
ForceSetActiveAnimation(animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID SpriteComponent::ForceSetActiveAnimation(IN Handle animation)
|
||||||
|
{
|
||||||
|
IA_RELEASE_ASSERT((animation != INVALID_HANDLE) && (animation < m_animations.size()));
|
||||||
|
m_prevAnimationKeyFrameIndex = 0;
|
||||||
|
m_activeAnimation = m_animations[animation];
|
||||||
|
|
||||||
|
m_prevAnimationKeyFrame = GetKeyFrame(m_prevAnimationKeyFrameIndex + 0);
|
||||||
|
m_nextAnimationKeyFrame = GetKeyFrame(m_prevAnimationKeyFrameIndex + 1);
|
||||||
|
|
||||||
|
m_currentAnimationState = m_prevAnimationKeyFrame;
|
||||||
|
m_activeAnimationHandle = animation;
|
||||||
|
|
||||||
|
SetTexture(m_currentAnimationState.Texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID SpriteComponent::SetAnimationFrame(IN INT32 animation, IN INT32 frame)
|
||||||
|
{
|
||||||
|
m_activeAnimation = {};
|
||||||
|
m_currentAnimationState = m_animations[animation].Keys[frame];
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID SpriteComponent::UpdateAnimation()
|
||||||
|
{
|
||||||
|
const auto keyCount = m_activeAnimation.Keys.size();
|
||||||
|
if (keyCount <= 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_currentAnimationState.ShouldInterpolate)
|
||||||
|
{
|
||||||
|
const auto t = m_timelinePosition / m_prevAnimationKeyFrame.Duration;
|
||||||
|
#define INTERP_PROPERTY(name) \
|
||||||
|
m_currentAnimationState.name = \
|
||||||
|
m_prevAnimationKeyFrame.name + (m_nextAnimationKeyFrame.name - m_prevAnimationKeyFrame.name) * t;
|
||||||
|
|
||||||
|
INTERP_PROPERTY(Position);
|
||||||
|
INTERP_PROPERTY(Rotation);
|
||||||
|
INTERP_PROPERTY(Scale);
|
||||||
|
INTERP_PROPERTY(ColorOverlay);
|
||||||
|
|
||||||
|
#undef INTERP_PROPERTY
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_timelinePosition >= m_prevAnimationKeyFrame.Duration)
|
||||||
|
{
|
||||||
|
m_prevAnimationKeyFrameIndex = (m_prevAnimationKeyFrameIndex + 1) % keyCount;
|
||||||
|
if (!m_prevAnimationKeyFrameIndex && !m_activeAnimation.ShouldLoop)
|
||||||
|
{
|
||||||
|
m_activeAnimation = {};
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_prevAnimationKeyFrame = GetKeyFrame(m_prevAnimationKeyFrameIndex + 0);
|
||||||
|
m_nextAnimationKeyFrame = GetKeyFrame(m_prevAnimationKeyFrameIndex + 1);
|
||||||
|
m_currentAnimationState = m_prevAnimationKeyFrame;
|
||||||
|
m_timelinePosition = 0;
|
||||||
|
}
|
||||||
|
m_timelinePosition += Engine::GetFrameDeltaTime() * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
SpriteComponent::AnimationKeyFrame SpriteComponent::GetKeyFrame(IN INT32 index)
|
||||||
|
{
|
||||||
|
return m_activeAnimation.Keys[index % m_activeAnimation.Keys.size()];
|
||||||
|
}
|
||||||
|
} // namespace ia::iae
|
||||||
25
Engine/Src/Imp/CPP/Nodes/SpriteNode.cpp
Normal file
25
Engine/Src/Imp/CPP/Nodes/SpriteNode.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// IAEngine: 2D Game Engine by IA
|
||||||
|
// Copyright (C) 2025 IASoft (PVT) LTD (oss@iasoft.dev)
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include <IAEngine/Engine.hpp>
|
||||||
|
#include <IAEngine/Nodes/SpriteNode.hpp>
|
||||||
|
|
||||||
|
namespace ia::iae
|
||||||
|
{
|
||||||
|
SpriteNode::SpriteNode(IN CONST String &name) : Node2D(name), m_spriteComponent(AddComponent<SpriteComponent>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
} // namespace ia::iae
|
||||||
@ -16,12 +16,12 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <IACore/Map.hpp>
|
#include <IACore/Exception.hpp>
|
||||||
#include <IACore/Logger.hpp>
|
#include <IACore/Logger.hpp>
|
||||||
|
#include <IACore/Map.hpp>
|
||||||
#include <IACore/Memory.hpp>
|
#include <IACore/Memory.hpp>
|
||||||
#include <IACore/String.hpp>
|
#include <IACore/String.hpp>
|
||||||
#include <IACore/Vector.hpp>
|
#include <IACore/Vector.hpp>
|
||||||
#include <IACore/Exception.hpp>
|
|
||||||
|
|
||||||
#include <IAEngine/glm/ext/matrix_clip_space.hpp>
|
#include <IAEngine/glm/ext/matrix_clip_space.hpp>
|
||||||
#include <IAEngine/glm/ext/matrix_transform.hpp>
|
#include <IAEngine/glm/ext/matrix_transform.hpp>
|
||||||
@ -111,7 +111,22 @@ namespace ia::iae
|
|||||||
|
|
||||||
Vec4 GetAsFloatVec() CONST
|
Vec4 GetAsFloatVec() CONST
|
||||||
{
|
{
|
||||||
return {(FLOAT32)R/255.0f, (FLOAT32)G/255.0f, (FLOAT32)B/255.0f, (FLOAT32)A/255.0f};
|
return {(FLOAT32) R / 255.0f, (FLOAT32) G / 255.0f, (FLOAT32) B / 255.0f, (FLOAT32) A / 255.0f};
|
||||||
|
}
|
||||||
|
|
||||||
|
Color operator+(IN CONST Color &other) CONST
|
||||||
|
{
|
||||||
|
return Color{(UINT8) (R + other.R), (UINT8) (G + other.G), (UINT8) (B + other.B), (UINT8) (A + other.A)};
|
||||||
|
}
|
||||||
|
|
||||||
|
Color operator-(IN CONST Color &other) CONST
|
||||||
|
{
|
||||||
|
return Color{(UINT8) (R - other.R), (UINT8) (G - other.G), (UINT8) (B - other.B), (UINT8) (A - other.A)};
|
||||||
|
}
|
||||||
|
|
||||||
|
Color operator*(IN FLOAT32 v) CONST
|
||||||
|
{
|
||||||
|
return Color{(UINT8) (R * v), (UINT8) (G * v), (UINT8) (B * v), (UINT8) (A * v)};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,88 @@
|
|||||||
|
// IAEngine: 2D Game Engine by IA
|
||||||
|
// Copyright (C) 2025 IASoft (PVT) LTD (oss@iasoft.dev)
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <IAEngine/Components/TextureComponent.hpp>
|
||||||
|
|
||||||
|
namespace ia::iae
|
||||||
|
{
|
||||||
|
class SpriteComponent : public TextureComponent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct AnimationKeyFrame
|
||||||
|
{
|
||||||
|
Handle Texture;
|
||||||
|
INT32 Duration{100};
|
||||||
|
BOOL ShouldInterpolate{};
|
||||||
|
|
||||||
|
FLOAT32 Rotation{};
|
||||||
|
Vec2 Position{};
|
||||||
|
Vec2 Scale{1.0f, 1.0f};
|
||||||
|
Color ColorOverlay{0xFF, 0xFF, 0xFF, 0xFF};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Animation
|
||||||
|
{
|
||||||
|
BOOL ShouldLoop{false};
|
||||||
|
Vector<AnimationKeyFrame> Keys;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
SpriteComponent(IN Node2D *node);
|
||||||
|
|
||||||
|
public:
|
||||||
|
VIRTUAL VOID Draw();
|
||||||
|
VIRTUAL VOID DebugDraw();
|
||||||
|
|
||||||
|
VIRTUAL VOID Update();
|
||||||
|
VIRTUAL VOID FixedUpdate();
|
||||||
|
|
||||||
|
public:
|
||||||
|
Handle AddAnimation(IN CONST Animation &animation);
|
||||||
|
|
||||||
|
VOID SetActiveAnimation(IN Handle animation);
|
||||||
|
VOID ForceSetActiveAnimation(IN Handle animation);
|
||||||
|
|
||||||
|
VOID SetAnimationFrame(IN INT32 animation, IN INT32 frame);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Vector<Animation> &Animations()
|
||||||
|
{
|
||||||
|
return m_animations;
|
||||||
|
}
|
||||||
|
|
||||||
|
CONST Vector<Animation> &Animations() CONST
|
||||||
|
{
|
||||||
|
return m_animations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
VOID UpdateAnimation();
|
||||||
|
|
||||||
|
AnimationKeyFrame GetKeyFrame(IN INT32 index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
FLOAT32 m_timelinePosition{};
|
||||||
|
Animation m_activeAnimation{};
|
||||||
|
Handle m_activeAnimationHandle{INVALID_HANDLE};
|
||||||
|
Vector<Animation> m_animations;
|
||||||
|
AnimationKeyFrame m_currentAnimationState{};
|
||||||
|
AnimationKeyFrame m_nextAnimationKeyFrame{};
|
||||||
|
AnimationKeyFrame m_prevAnimationKeyFrame{};
|
||||||
|
INT32 m_prevAnimationKeyFrameIndex{};
|
||||||
|
};
|
||||||
|
} // namespace ia::iae
|
||||||
@ -26,11 +26,11 @@ namespace ia::iae
|
|||||||
TextureComponent(IN Node2D *node);
|
TextureComponent(IN Node2D *node);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VOID Draw();
|
VIRTUAL VOID Draw();
|
||||||
VOID DebugDraw();
|
VIRTUAL VOID DebugDraw();
|
||||||
|
|
||||||
VOID Update();
|
VIRTUAL VOID Update();
|
||||||
VOID FixedUpdate();
|
VIRTUAL VOID FixedUpdate();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
VOID SetTexture(IN Handle image);
|
VOID SetTexture(IN Handle image);
|
||||||
@ -97,6 +97,6 @@ namespace ia::iae
|
|||||||
Vec2 m_drawnSize{};
|
Vec2 m_drawnSize{};
|
||||||
|
|
||||||
Vec2 m_textureExtent{};
|
Vec2 m_textureExtent{};
|
||||||
Handle m_texture{INVALID_HANDLE};
|
Handle m_texture{0};
|
||||||
};
|
};
|
||||||
} // namespace ia::iae
|
} // namespace ia::iae
|
||||||
@ -16,10 +16,23 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <IAEngine/Nodes/Node2D.hpp>
|
|
||||||
#include <IAEngine/Components/SpriteComponent.hpp>
|
#include <IAEngine/Components/SpriteComponent.hpp>
|
||||||
|
#include <IAEngine/Nodes/Node2D.hpp>
|
||||||
|
|
||||||
namespace ia::iae
|
namespace ia::iae
|
||||||
{
|
{
|
||||||
|
class SpriteNode : public Node2D
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SpriteNode(IN CONST String &name);
|
||||||
|
|
||||||
}
|
public:
|
||||||
|
SpriteComponent *GetSpriteComponent()
|
||||||
|
{
|
||||||
|
return m_spriteComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SpriteComponent *CONST m_spriteComponent{};
|
||||||
|
};
|
||||||
|
} // namespace ia::iae
|
||||||
Reference in New Issue
Block a user