加入 Node节点类 还未测试新框架
This commit is contained in:
26
source/EngineFrame/Attribute/Bits.h
Normal file
26
source/EngineFrame/Attribute/Bits.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include <type_traits>
|
||||
|
||||
namespace bits
|
||||
{
|
||||
template <typename _Ty>
|
||||
inline void Set(_Ty &old, _Ty flag)
|
||||
{
|
||||
static_assert(std::is_arithmetic<_Ty>::value, "_Ty must be an arithmetic type");
|
||||
old |= flag;
|
||||
}
|
||||
|
||||
template <typename _Ty>
|
||||
inline void Unset(_Ty &old, _Ty flag)
|
||||
{
|
||||
static_assert(std::is_arithmetic<_Ty>::value, "_Ty must be an arithmetic type");
|
||||
old &= ~flag;
|
||||
}
|
||||
|
||||
template <typename _Ty>
|
||||
inline bool Has(_Ty old, _Ty flag)
|
||||
{
|
||||
static_assert(std::is_arithmetic<_Ty>::value, "_Ty must be an arithmetic type");
|
||||
return !!(old & flag);
|
||||
}
|
||||
}
|
||||
57
source/EngineFrame/Attribute/Flag.h
Normal file
57
source/EngineFrame/Attribute/Flag.h
Normal file
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
#include <cstdint> // uint8_t
|
||||
#include "Bits.h"
|
||||
template <typename _Ty>
|
||||
class Flag
|
||||
{
|
||||
public:
|
||||
static_assert(std::is_arithmetic<_Ty>::value, "_Ty must be an arithmetic type");
|
||||
|
||||
typedef _Ty value_type;
|
||||
|
||||
_Ty value;
|
||||
|
||||
inline Flag()
|
||||
: value()
|
||||
{
|
||||
}
|
||||
|
||||
inline Flag(_Ty value)
|
||||
: value(value)
|
||||
{
|
||||
}
|
||||
|
||||
inline void Set(_Ty value)
|
||||
{
|
||||
bits::Set(this->value, value);
|
||||
}
|
||||
|
||||
inline void Unset(_Ty value)
|
||||
{
|
||||
bits::Unset(this->value, value);
|
||||
}
|
||||
|
||||
inline bool Has(_Ty value) const
|
||||
{
|
||||
return bits::Has(this->value, value);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename _Ty>
|
||||
struct IsFlag : public std::false_type
|
||||
{
|
||||
};
|
||||
|
||||
template <typename _Ty>
|
||||
struct IsFlag<Flag<_Ty>> : public std::true_type
|
||||
{
|
||||
};
|
||||
|
||||
typedef Flag<uint8_t> FlagUint8;
|
||||
typedef Flag<uint16_t> FlagUint16;
|
||||
typedef Flag<uint32_t> FlagUint32;
|
||||
typedef Flag<uint64_t> FlagUint64;
|
||||
typedef Flag<int8_t> FlagInt8;
|
||||
typedef Flag<int16_t> FlagInt16;
|
||||
typedef Flag<int32_t> FlagInt32;
|
||||
typedef Flag<int64_t> FlagInt64;
|
||||
61
source/EngineFrame/Attribute/Y_Transform.cpp
Normal file
61
source/EngineFrame/Attribute/Y_Transform.cpp
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "Y_Transform.h"
|
||||
#include <cmath>
|
||||
Y_Transform::Y_Transform() : position(0.f, 0.f), scale(1.0f, 1.0f), skew(0.f, 0.f), rotation(0.f)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Matrix3x2 Y_Transform::ToMatrix() const
|
||||
{
|
||||
// 将角度转换为弧度
|
||||
float rotRad = glm::radians(rotation);
|
||||
float skewXRad = glm::radians(skew.x);
|
||||
float skewYRad = glm::radians(skew.y);
|
||||
|
||||
// 计算旋转的正弦和余弦
|
||||
float cosRot = std::cos(rotRad);
|
||||
float sinRot = std::sin(rotRad);
|
||||
|
||||
// 计算错切的正切值
|
||||
float tanSkewX = std::tan(skewXRad);
|
||||
float tanSkewY = std::tan(skewYRad);
|
||||
|
||||
// 构造基础变换矩阵(缩放 × 错切 × 旋转的组合)
|
||||
// 注意:矩阵乘法顺序为 旋转 × 错切 × 缩放(从右向左应用)
|
||||
float m00 = scale.x * (cosRot - sinRot * tanSkewY);
|
||||
float m01 = scale.y * (-sinRot + cosRot * tanSkewX);
|
||||
float m10 = scale.x * (sinRot + cosRot * tanSkewY);
|
||||
float m11 = scale.y * (cosRot + sinRot * tanSkewX);
|
||||
|
||||
// 平移分量
|
||||
float tx = position.x;
|
||||
float ty = position.y;
|
||||
|
||||
// 构造并返回 3x2 矩阵(假设 Matrix3x2 可通过此方式初始化)
|
||||
return Matrix3x2(m00, m01, m10, m11, tx, ty);
|
||||
}
|
||||
|
||||
glm::mat4 Y_Transform::GetTransformMatrix() const
|
||||
{
|
||||
// 缩放矩阵(Scale)
|
||||
glm::mat4 scaleMat = glm::mat4(1.0f); // 单位矩阵
|
||||
scaleMat[0][0] = scale.x; // x轴缩放
|
||||
scaleMat[1][1] = scale.y; // y轴缩放
|
||||
|
||||
// 错切矩阵(Skew):先将角度转为弧度
|
||||
float skewX = glm::radians(skew.x); // 沿y轴错切角度(x方向倾斜)
|
||||
float skewY = glm::radians(skew.y); // 沿x轴错切角度(y方向倾斜)
|
||||
glm::mat4 skewMat = glm::mat4(1.0f);
|
||||
skewMat[0][1] = tan(skewX); // x方向错切因子(影响y轴)
|
||||
skewMat[1][0] = tan(skewY); // y方向错切因子(影响x轴)
|
||||
|
||||
// 旋转矩阵(Rotation):绕z轴旋转,角度转弧度
|
||||
float rotRad = glm::radians(rotation);
|
||||
glm::mat4 rotMat = glm::rotate(glm::mat4(1.0f), rotRad, glm::vec3(0, 0, 1));
|
||||
|
||||
// 平移矩阵(Translation)
|
||||
glm::mat4 transMat = glm::translate(glm::mat4(1.0f), glm::vec3(position, 0.0f));
|
||||
|
||||
// 组合变换矩阵:平移 × 旋转 × 错切 × 缩放(注意乘法顺序,从右向左应用)
|
||||
return transMat * rotMat * skewMat * scaleMat;
|
||||
}
|
||||
26
source/EngineFrame/Attribute/Y_Transform.h
Normal file
26
source/EngineFrame/Attribute/Y_Transform.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include "math/Math.h"
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/ext/matrix_clip_space.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
class Y_Transform
|
||||
{
|
||||
public:
|
||||
float rotation; ///< 旋转
|
||||
glm::vec2 position; ///< 坐标
|
||||
glm::vec2 scale; ///< 缩放
|
||||
glm::vec2 skew; ///< 错切角度
|
||||
|
||||
public:
|
||||
Y_Transform(/* args */);
|
||||
|
||||
bool IsFast() const
|
||||
{
|
||||
return skew.x == 0.f && skew.y == 0.f &&
|
||||
scale.x == 1.f && scale.y == 1.f &&
|
||||
rotation == 0.f;
|
||||
}
|
||||
|
||||
Matrix3x2 ToMatrix() const;
|
||||
glm::mat4 GetTransformMatrix() const;
|
||||
};
|
||||
@@ -18,8 +18,17 @@ void Actor::Init()
|
||||
addTag(Tag::UPDATE);
|
||||
}
|
||||
|
||||
void Actor::Update(float deltaTime)
|
||||
{
|
||||
if (!Visible)
|
||||
return;
|
||||
BaseNode::Update(deltaTime);
|
||||
}
|
||||
|
||||
void Actor::Render()
|
||||
{
|
||||
if (!Visible)
|
||||
return;
|
||||
// 如果有裁切视口
|
||||
if (this->_CropViewportFlag)
|
||||
{
|
||||
@@ -34,16 +43,6 @@ void Actor::Render()
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::AddComponent(RefPtr<Component> Component)
|
||||
{
|
||||
BaseNode::AddChild(Component);
|
||||
}
|
||||
|
||||
void Actor::RemoveComponent(RefPtr<Component> Component)
|
||||
{
|
||||
BaseNode::RemoveChild(Component);
|
||||
}
|
||||
|
||||
void Actor::SetCropViewport(SDL_Rect CropViewport)
|
||||
{
|
||||
if (CropViewport.x == 0 && CropViewport.y == 0 && CropViewport.w == 0 && CropViewport.h == 0)
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
#include "EngineFrame/Base/BaseNode.h"
|
||||
#include "EngineFrame/Component/Component.h"
|
||||
#include "Tool/IntrusiveList.hpp"
|
||||
class Scene;
|
||||
/**
|
||||
@@ -21,9 +20,8 @@ public:
|
||||
|
||||
public:
|
||||
void Init() override;
|
||||
void Update(float deltaTime) override;
|
||||
void Render() override;
|
||||
void AddComponent(RefPtr<Component> Component);
|
||||
void RemoveComponent(RefPtr<Component> Component);
|
||||
|
||||
// 设置裁切视口(放在Actor里 他与他的子对象都会被裁切)
|
||||
void SetCropViewport(SDL_Rect CropViewport);
|
||||
@@ -27,11 +27,6 @@ void BaseNode::HandleEvents(SDL_Event *e)
|
||||
|
||||
void BaseNode::Update(float deltaTime)
|
||||
{
|
||||
// 如果有回调函数,则调用回调函数
|
||||
if (cb_update_)
|
||||
{
|
||||
cb_update_(deltaTime);
|
||||
}
|
||||
// 如果有子节点并含有刷新标签,则更新子节点
|
||||
RefPtr<BaseNode> child = m_BaseNodes.GetFirst();
|
||||
while (child)
|
||||
@@ -40,6 +35,14 @@ void BaseNode::Update(float deltaTime)
|
||||
child->Update(deltaTime);
|
||||
child = child->GetNext();
|
||||
}
|
||||
// 如果有回调函数,则调用回调函数
|
||||
if (cb_update_.size() > 0)
|
||||
{
|
||||
for (auto &cb : cb_update_)
|
||||
{
|
||||
cb.second(deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BaseNode::PreRender()
|
||||
@@ -53,7 +56,6 @@ void BaseNode::PreRender()
|
||||
child = child->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
void BaseNode::Render()
|
||||
{
|
||||
// 如果有子节点并含有渲染标签,则渲染子节点
|
||||
@@ -70,9 +72,14 @@ void BaseNode::Clear()
|
||||
{
|
||||
}
|
||||
|
||||
void BaseNode::SetCallbackOnUpdate(const UpdateCallback &cb)
|
||||
void BaseNode::SetCallbackOnUpdate(std::string Key, const UpdateCallback &cb)
|
||||
{
|
||||
cb_update_ = cb;
|
||||
cb_update_[Key] = cb;
|
||||
}
|
||||
|
||||
void BaseNode::RemoveCallbackOnUpdate(std::string Key)
|
||||
{
|
||||
cb_update_.erase(Key);
|
||||
}
|
||||
|
||||
void BaseNode::SetChildIterationTransform()
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
|
||||
public:
|
||||
// 更新时的回调函数
|
||||
UpdateCallback cb_update_;
|
||||
std::map<std::string ,UpdateCallback> cb_update_;
|
||||
// 节点名称
|
||||
std::string m_Name;
|
||||
// 子节点列表
|
||||
@@ -60,8 +60,9 @@ public:
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置更新时的回调函数
|
||||
void SetCallbackOnUpdate(const UpdateCallback &cb);
|
||||
|
||||
void SetCallbackOnUpdate(std::string Key,const UpdateCallback &cb);
|
||||
void RemoveCallbackOnUpdate(std::string Key);
|
||||
|
||||
void SetChildIterationTransform();
|
||||
|
||||
// 计算渲染信息
|
||||
|
||||
549
source/EngineFrame/Base/Node.cpp
Normal file
549
source/EngineFrame/Base/Node.cpp
Normal file
@@ -0,0 +1,549 @@
|
||||
#include "Node.h"
|
||||
#include "EngineCore/Game.h"
|
||||
void Node::Init()
|
||||
{
|
||||
}
|
||||
void Node::HandleEvents(SDL_Event *e)
|
||||
{
|
||||
}
|
||||
inline void Node::Update(float deltaTime)
|
||||
{
|
||||
if (children_.IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<Node> child = children_.GetFirst();
|
||||
while (child)
|
||||
{
|
||||
if (child->GetZOrder() >= 0)
|
||||
break;
|
||||
|
||||
child->Update(deltaTime);
|
||||
child = child->GetNext();
|
||||
}
|
||||
|
||||
UpdateSelf(deltaTime);
|
||||
|
||||
|
||||
while (child)
|
||||
{
|
||||
child->Update(deltaTime);
|
||||
child = child->GetNext();
|
||||
}
|
||||
}
|
||||
inline void Node::PreRender()
|
||||
{
|
||||
}
|
||||
inline void Node::Render()
|
||||
{
|
||||
}
|
||||
void Node::Clear()
|
||||
{
|
||||
}
|
||||
|
||||
void Node::UpdateSelf(float deltaTime)
|
||||
{
|
||||
// 如果有回调函数,则调用回调函数
|
||||
if (cb_update_.size() > 0)
|
||||
{
|
||||
for (auto &cb : cb_update_)
|
||||
{
|
||||
cb.second(deltaTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Node::RemoveFromParent()
|
||||
{
|
||||
if (parent_)
|
||||
{
|
||||
parent_->RemoveChild(this);
|
||||
}
|
||||
}
|
||||
inline void Node::PauseUpdating()
|
||||
{
|
||||
update_pausing_ = true;
|
||||
}
|
||||
inline void Node::ResumeUpdating()
|
||||
{
|
||||
update_pausing_ = false;
|
||||
}
|
||||
inline bool Node::IsUpdatePausing() const
|
||||
{
|
||||
return update_pausing_;
|
||||
}
|
||||
|
||||
void Node::SetCallbackOnUpdate(std::string Key, const UpdateCallback &cb)
|
||||
{
|
||||
cb_update_[Key] = cb;
|
||||
}
|
||||
|
||||
void Node::RemoveCallbackOnUpdate(std::string Key)
|
||||
{
|
||||
cb_update_.erase(Key);
|
||||
}
|
||||
|
||||
bool Node::ContainsPoint(const glm::vec2 &point) const
|
||||
{
|
||||
// if (size_.x == 0.f || size_.y == 0.f)
|
||||
return false;
|
||||
// glm::vec2 local = ConvertToLocal(point);
|
||||
// return local.x >= 0 && local.y >= 0 && local.x <= size_.x && local.y <= size_.y;
|
||||
}
|
||||
|
||||
glm::vec2 Node::ConvertToLocal(const glm::vec2 &point) const
|
||||
{
|
||||
glm::vec2 local = GetTransformInverseMatrix().Transform(point);
|
||||
return local;
|
||||
}
|
||||
|
||||
glm::vec2 Node::ConvertToWorld(const glm::vec2 &point) const
|
||||
{
|
||||
glm::vec2 world = GetTransformMatrix().Transform(point);
|
||||
return world;
|
||||
}
|
||||
|
||||
void Node::ShowBorder(bool show)
|
||||
{
|
||||
show_border_ = show;
|
||||
}
|
||||
|
||||
Node::Node() : visible_(true), update_pausing_(false), show_border_(false), parent_(nullptr), anchor_(0.0f, 0.0f), z_order_(0), opacity_(1.f), name_("Node")
|
||||
{
|
||||
Game::GetInstance().m_nodeCount++;
|
||||
}
|
||||
|
||||
Node::~Node()
|
||||
{
|
||||
Game::GetInstance().m_nodeCount--;
|
||||
RemoveAllChildren();
|
||||
}
|
||||
|
||||
void Node::UpdateTransform() const
|
||||
{
|
||||
if (!dirty_flag_.Has(DirtyFlag::DirtyTransform))
|
||||
return;
|
||||
dirty_flag_.Unset(DirtyFlag::DirtyTransform);
|
||||
dirty_flag_.Set(DirtyFlag::DirtyTransformInverse);
|
||||
dirty_flag_.Set(DirtyFlag::DirtyVisibility);
|
||||
|
||||
if (transform_.IsFast())
|
||||
{
|
||||
transform_matrix_to_parent_ = Matrix3x2::Translation(transform_.position);
|
||||
}
|
||||
else
|
||||
{
|
||||
transform_matrix_to_parent_ = transform_.ToMatrix();
|
||||
}
|
||||
|
||||
glm::vec2 anchor_offset(-size_.width * anchor_.x, -size_.height * anchor_.y);
|
||||
transform_matrix_to_parent_.Translate(anchor_offset);
|
||||
|
||||
transform_matrix_ = transform_matrix_to_parent_;
|
||||
if (parent_)
|
||||
{
|
||||
transform_matrix_ *= parent_->transform_matrix_;
|
||||
}
|
||||
|
||||
for (const auto &child : children_)
|
||||
child->dirty_flag_.Set(DirtyFlag::DirtyTransform);
|
||||
}
|
||||
|
||||
void Node::UpdateTransformUpwards() const
|
||||
{
|
||||
if (parent_)
|
||||
{
|
||||
parent_->UpdateTransformUpwards();
|
||||
|
||||
if (parent_->dirty_flag_.Has(DirtyFlag::DirtyTransform))
|
||||
{
|
||||
dirty_flag_.Set(DirtyFlag::DirtyTransform);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateTransform();
|
||||
}
|
||||
|
||||
const Matrix3x2 &Node::GetTransformMatrix() const
|
||||
{
|
||||
UpdateTransformUpwards();
|
||||
return transform_matrix_;
|
||||
}
|
||||
|
||||
const Matrix3x2 &Node::GetTransformInverseMatrix() const
|
||||
{
|
||||
UpdateTransformUpwards();
|
||||
if (dirty_flag_.Has(DirtyFlag::DirtyTransformInverse))
|
||||
{
|
||||
dirty_flag_.Unset(DirtyFlag::DirtyTransformInverse);
|
||||
transform_matrix_inverse_ = transform_matrix_.Invert();
|
||||
}
|
||||
return transform_matrix_inverse_;
|
||||
}
|
||||
|
||||
const Matrix3x2 &Node::GetTransformMatrixToParent() const
|
||||
{
|
||||
UpdateTransformUpwards();
|
||||
return transform_matrix_to_parent_;
|
||||
}
|
||||
|
||||
void Node::Reorder()
|
||||
{
|
||||
if (parent_)
|
||||
{
|
||||
RefPtr<Node> me = this;
|
||||
|
||||
parent_->children_.Remove(me);
|
||||
|
||||
RefPtr<Node> sibling = parent_->children_.GetLast();
|
||||
|
||||
if (sibling && sibling->GetZOrder() > z_order_)
|
||||
{
|
||||
sibling = sibling->GetPrev();
|
||||
while (sibling)
|
||||
{
|
||||
if (sibling->GetZOrder() <= z_order_)
|
||||
break;
|
||||
sibling = sibling->GetPrev();
|
||||
}
|
||||
}
|
||||
|
||||
if (sibling)
|
||||
{
|
||||
parent_->children_.InsertAfter(me, sibling);
|
||||
}
|
||||
else
|
||||
{
|
||||
parent_->children_.PushFront(me);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void Node::RemoveAllChildren()
|
||||
{
|
||||
RefPtr<Node> next;
|
||||
for (RefPtr<Node> child = children_.GetFirst(); child; child = next)
|
||||
{
|
||||
next = child->GetNext();
|
||||
RemoveChild(child);
|
||||
}
|
||||
}
|
||||
|
||||
inline bool Node::IsVisible() const
|
||||
{
|
||||
return visible_;
|
||||
}
|
||||
|
||||
inline int Node::GetZOrder() const
|
||||
{
|
||||
return z_order_;
|
||||
}
|
||||
|
||||
inline glm::vec2 Node::GetPosition() const
|
||||
{
|
||||
return transform_.position;
|
||||
}
|
||||
|
||||
inline float Node::GetPositionX() const
|
||||
{
|
||||
return GetPosition().x;
|
||||
}
|
||||
|
||||
inline float Node::GetPositionY() const
|
||||
{
|
||||
return GetPosition().y;
|
||||
}
|
||||
|
||||
inline VecSize Node::GetSize() const
|
||||
{
|
||||
return size_;
|
||||
}
|
||||
|
||||
inline float Node::GetWidth() const
|
||||
{
|
||||
return GetSize().width;
|
||||
}
|
||||
|
||||
inline float Node::GetHeight() const
|
||||
{
|
||||
return GetSize().height;
|
||||
}
|
||||
|
||||
inline float Node::GetScaledWidth() const
|
||||
{
|
||||
return GetWidth() * GetScaleX();
|
||||
}
|
||||
|
||||
inline float Node::GetScaledHeight() const
|
||||
{
|
||||
return GetHeight() * GetScaleY();
|
||||
}
|
||||
|
||||
inline VecSize Node::GetScaledSize() const
|
||||
{
|
||||
return VecSize{GetScaledWidth(), GetScaledHeight()};
|
||||
}
|
||||
|
||||
inline glm::vec2 Node::GetAnchor() const
|
||||
{
|
||||
return anchor_;
|
||||
}
|
||||
|
||||
inline float Node::GetAnchorX() const
|
||||
{
|
||||
return GetAnchor().x;
|
||||
}
|
||||
|
||||
inline float Node::GetAnchorY() const
|
||||
{
|
||||
return GetAnchor().y;
|
||||
}
|
||||
|
||||
inline float Node::GetOpacity() const
|
||||
{
|
||||
return opacity_;
|
||||
}
|
||||
|
||||
inline float Node::GetRotation() const
|
||||
{
|
||||
return transform_.rotation;
|
||||
}
|
||||
|
||||
inline glm::vec2 Node::GetScale() const
|
||||
{
|
||||
return transform_.scale;
|
||||
}
|
||||
|
||||
inline float Node::GetScaleX() const
|
||||
{
|
||||
return GetScale().x;
|
||||
}
|
||||
|
||||
inline float Node::GetScaleY() const
|
||||
{
|
||||
return GetScale().y;
|
||||
}
|
||||
|
||||
inline glm::vec2 Node::GetSkew() const
|
||||
{
|
||||
return transform_.skew;
|
||||
}
|
||||
|
||||
inline float Node::GetSkewX() const
|
||||
{
|
||||
return GetSkew().x;
|
||||
}
|
||||
|
||||
inline float Node::GetSkewY() const
|
||||
{
|
||||
return GetSkew().y;
|
||||
}
|
||||
|
||||
inline Y_Transform Node::GetTransform() const
|
||||
{
|
||||
return transform_;
|
||||
}
|
||||
|
||||
inline Node *Node::GetParent() const
|
||||
{
|
||||
return parent_;
|
||||
}
|
||||
|
||||
inline void Node::SetVisible(bool val)
|
||||
{
|
||||
visible_ = val;
|
||||
}
|
||||
|
||||
inline void Node::SetName(std::string name)
|
||||
{
|
||||
name_ = name;
|
||||
}
|
||||
|
||||
inline void Node::SetPosition(const glm::vec2 &pos)
|
||||
{
|
||||
if (transform_.position == pos)
|
||||
return;
|
||||
|
||||
transform_.position = pos;
|
||||
dirty_flag_.Set(DirtyFlag::DirtyTransform);
|
||||
}
|
||||
|
||||
inline void Node::SetPosition(float x, float y)
|
||||
{
|
||||
this->SetPosition(glm::vec2(x, y));
|
||||
}
|
||||
|
||||
inline void Node::SetPositionX(float x)
|
||||
{
|
||||
this->SetPosition(glm::vec2(x, GetPosition().y));
|
||||
}
|
||||
|
||||
inline void Node::SetPositionY(float y)
|
||||
{
|
||||
this->SetPosition(glm::vec2(GetPosition().x, y));
|
||||
}
|
||||
|
||||
inline void Node::MoveTo(const glm::vec2 &p)
|
||||
{
|
||||
this->SetPosition(p);
|
||||
}
|
||||
|
||||
inline void Node::MoveTo(float x, float y)
|
||||
{
|
||||
this->SetPosition(glm::vec2(x, y));
|
||||
}
|
||||
|
||||
inline void Node::MoveBy(const glm::vec2 &trans)
|
||||
{
|
||||
this->SetPosition(transform_.position.x + trans.x, transform_.position.y + trans.y);
|
||||
}
|
||||
|
||||
inline void Node::MoveBy(float trans_x, float trans_y)
|
||||
{
|
||||
this->MoveBy(glm::vec2(trans_x, trans_y));
|
||||
}
|
||||
|
||||
inline void Node::SetScale(const glm::vec2 &scale)
|
||||
{
|
||||
if (transform_.scale == scale)
|
||||
return;
|
||||
|
||||
transform_.scale = scale;
|
||||
dirty_flag_.Set(DirtyFlag::DirtyTransform);
|
||||
}
|
||||
|
||||
inline void Node::SetScale(float scalex, float scaley)
|
||||
{
|
||||
this->SetScale(glm::vec2(scalex, scaley));
|
||||
}
|
||||
|
||||
inline void Node::SetSkew(const glm::vec2 &skew)
|
||||
{
|
||||
if (transform_.skew == skew)
|
||||
return;
|
||||
|
||||
transform_.skew = skew;
|
||||
dirty_flag_.Set(DirtyFlag::DirtyTransform);
|
||||
}
|
||||
|
||||
inline void Node::SetSkew(float skewx, float skewy)
|
||||
{
|
||||
this->SetSkew(glm::vec2(skewx, skewy));
|
||||
}
|
||||
|
||||
inline void Node::SetRotation(float rotation)
|
||||
{
|
||||
if (transform_.rotation == rotation)
|
||||
return;
|
||||
|
||||
transform_.rotation = rotation;
|
||||
dirty_flag_.Set(DirtyFlag::DirtyTransform);
|
||||
}
|
||||
|
||||
inline void Node::SetAnchor(const glm::vec2 &anchor)
|
||||
{
|
||||
if (anchor_ == anchor)
|
||||
return;
|
||||
|
||||
anchor_ = anchor;
|
||||
dirty_flag_.Set(DirtyFlag::DirtyTransform);
|
||||
}
|
||||
|
||||
inline void Node::SetAnchor(float anchorx, float anchory)
|
||||
{
|
||||
this->SetAnchor(glm::vec2(anchorx, anchory));
|
||||
}
|
||||
|
||||
inline void Node::SetSize(const VecSize &size)
|
||||
{
|
||||
if (size_ == size)
|
||||
return;
|
||||
|
||||
size_ = size;
|
||||
dirty_flag_.Set(DirtyFlag::DirtyTransform);
|
||||
}
|
||||
|
||||
inline void Node::SetSize(float width, float height)
|
||||
{
|
||||
this->SetSize(VecSize{width, height});
|
||||
}
|
||||
|
||||
inline void Node::SetWidth(float width)
|
||||
{
|
||||
this->SetSize(width, GetHeight());
|
||||
}
|
||||
|
||||
inline void Node::SetHeight(float height)
|
||||
{
|
||||
this->SetSize(GetWidth(), height);
|
||||
}
|
||||
|
||||
inline void Node::SetOpacity(float opacity)
|
||||
{
|
||||
if (opacity_ == opacity)
|
||||
return;
|
||||
|
||||
opacity_ = std::min(std::max(opacity, 0.f), 1.f);
|
||||
dirty_flag_.Set(DirtyFlag::DirtyOpacity);
|
||||
}
|
||||
|
||||
inline void Node::SetTransform(const Y_Transform &transform)
|
||||
{
|
||||
transform_ = transform;
|
||||
dirty_flag_.Set(DirtyFlag::DirtyTransform);
|
||||
}
|
||||
|
||||
inline void Node::SetZOrder(int zorder)
|
||||
{
|
||||
if (z_order_ != zorder)
|
||||
{
|
||||
z_order_ = zorder;
|
||||
Reorder();
|
||||
}
|
||||
}
|
||||
|
||||
void Node::AddChild(RefPtr<Node> child)
|
||||
{
|
||||
if (child)
|
||||
{
|
||||
assert(!child->parent_ && "Actor::AddChild failed, the actor to be added already has a parent");
|
||||
|
||||
children_.PushBack(child);
|
||||
child->parent_ = this;
|
||||
|
||||
child->dirty_flag_.Set(DirtyFlag::DirtyTransform);
|
||||
child->dirty_flag_.Set(DirtyFlag::DirtyOpacity);
|
||||
child->Reorder();
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_LogError(0, "Actor::AddChild failed, NULL pointer exception");
|
||||
}
|
||||
}
|
||||
|
||||
Node::NodeList &Node::GetAllChildren()
|
||||
{
|
||||
return children_;
|
||||
}
|
||||
|
||||
const Node::NodeList &Node::GetAllChildren() const
|
||||
{
|
||||
return children_;
|
||||
}
|
||||
|
||||
inline void Node::RemoveChild(RefPtr<Node> child)
|
||||
{
|
||||
if (children_.IsEmpty())
|
||||
return;
|
||||
|
||||
if (child)
|
||||
{
|
||||
child->parent_ = nullptr;
|
||||
children_.Remove(child);
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_LogError(0, "Actor::RemoveChild failed, NULL pointer exception");
|
||||
}
|
||||
}
|
||||
355
source/EngineFrame/Base/Node.h
Normal file
355
source/EngineFrame/Base/Node.h
Normal file
@@ -0,0 +1,355 @@
|
||||
#pragma once
|
||||
#include <SDL.h>
|
||||
#include "EngineFrame/Attribute/Y_Transform.h"
|
||||
#include "EngineFrame/Attribute/Flag.h"
|
||||
#include "math/Math.h"
|
||||
#include "Tool/RefObject.h"
|
||||
#include "Tool/RefPtr.h"
|
||||
#include "Tool/IntrusiveList.hpp"
|
||||
|
||||
class Node : public RefObject, protected IntrusiveListValue<RefPtr<Node>>
|
||||
{
|
||||
public:
|
||||
typedef std::function<void(float deltaTime)> UpdateCallback;
|
||||
typedef IntrusiveList<RefPtr<Node>> NodeList;
|
||||
|
||||
using IntrusiveListValue<RefPtr<Node>>::GetNext;
|
||||
using IntrusiveListValue<RefPtr<Node>>::GetPrev;
|
||||
|
||||
private:
|
||||
/**变换属性 */
|
||||
Y_Transform transform_;
|
||||
/**变换矩阵 */
|
||||
mutable Matrix3x2 transform_matrix_;
|
||||
mutable Matrix3x2 transform_matrix_inverse_;
|
||||
mutable Matrix3x2 transform_matrix_to_parent_;
|
||||
/**更新时的回调函数 */
|
||||
std::map<std::string, UpdateCallback> cb_update_;
|
||||
/**锚点 */
|
||||
glm::vec2 anchor_;
|
||||
/**Z轴显示层级 */
|
||||
int z_order_;
|
||||
/**大小 */
|
||||
VecSize size_;
|
||||
/**透明度 */
|
||||
float opacity_;
|
||||
|
||||
/**是否可见 */
|
||||
bool visible_;
|
||||
/**是否暂停更新 */
|
||||
bool update_pausing_;
|
||||
/**是否显示边界 */
|
||||
bool show_border_;
|
||||
/**名称 */
|
||||
std::string name_;
|
||||
|
||||
/**父对象 */
|
||||
Node *parent_;
|
||||
/**子对象链表 */
|
||||
NodeList children_;
|
||||
/**标志 */
|
||||
mutable Flag<uint8_t> dirty_flag_;
|
||||
|
||||
public:
|
||||
virtual void Init();
|
||||
virtual void HandleEvents(SDL_Event *e);
|
||||
virtual void Update(float deltaTime);
|
||||
virtual void PreRender();
|
||||
virtual void Render();
|
||||
virtual void Clear();
|
||||
|
||||
void UpdateSelf(float dt);
|
||||
|
||||
|
||||
public:
|
||||
/// \~chinese
|
||||
/// @brief 获取显示状态
|
||||
bool IsVisible() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取 Z 轴顺序
|
||||
int GetZOrder() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取坐标
|
||||
glm::vec2 GetPosition() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取 x 坐标
|
||||
float GetPositionX() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取 y 坐标
|
||||
float GetPositionY() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取大小
|
||||
virtual VecSize GetSize() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取宽度
|
||||
float GetWidth() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取高度
|
||||
float GetHeight() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取缩放后的宽度
|
||||
float GetScaledWidth() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取缩放后的高度
|
||||
float GetScaledHeight() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取缩放后的大小
|
||||
VecSize GetScaledSize() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取锚点
|
||||
glm::vec2 GetAnchor() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取 x 方向锚点
|
||||
float GetAnchorX() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取 y 方向锚点
|
||||
float GetAnchorY() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取透明度
|
||||
float GetOpacity() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取旋转角度
|
||||
float GetRotation() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取缩放比例
|
||||
glm::vec2 GetScale() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取横向缩放比例
|
||||
float GetScaleX() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取纵向缩放比例
|
||||
float GetScaleY() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取错切角度
|
||||
glm::vec2 GetSkew() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取横向错切角度
|
||||
float GetSkewX() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取纵向错切角度
|
||||
float GetSkewY() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取变换
|
||||
Y_Transform GetTransform() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取父角色
|
||||
Node *GetParent() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置角色是否可见
|
||||
void SetVisible(bool val);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置名称
|
||||
void SetName(std::string name);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置坐标
|
||||
void SetPosition(const glm::vec2 &pos);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置坐标
|
||||
void SetPosition(float x, float y);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置横坐标
|
||||
void SetPositionX(float x);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置纵坐标
|
||||
void SetPositionY(float y);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 移动至坐标
|
||||
void MoveTo(const glm::vec2 &p);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 移动至坐标
|
||||
void MoveTo(float x, float y);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 移动相对坐标
|
||||
void MoveBy(const glm::vec2 &trans);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 移动相对坐标
|
||||
void MoveBy(float trans_x, float trans_y);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置缩放比例,默认为 (1.0, 1.0)
|
||||
void SetScale(const glm::vec2 &scale);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置缩放比例,默认为 (1.0, 1.0)
|
||||
void SetScale(float scalex, float scaley);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置错切角度,默认为 (0, 0)
|
||||
void SetSkew(const glm::vec2 &skew);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置错切角度,默认为 (0, 0)
|
||||
void SetSkew(float skewx, float skewy);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置旋转角度,默认为 0
|
||||
void SetRotation(float rotation);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置锚点位置,默认为 (0, 0), 范围 [0, 1]
|
||||
void SetAnchor(const glm::vec2 &anchor);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置锚点位置,默认为 (0, 0), 范围 [0, 1]
|
||||
void SetAnchor(float anchorx, float anchory);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 修改大小
|
||||
void SetSize(const VecSize &size);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 修改大小
|
||||
void SetSize(float width, float height);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 修改宽度
|
||||
void SetWidth(float width);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 修改高度
|
||||
void SetHeight(float height);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置透明度,默认为 1.0, 范围 [0, 1]
|
||||
void SetOpacity(float opacity);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置二维仿射变换
|
||||
void SetTransform(const Y_Transform &transform);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置 Z 轴顺序,默认为 0
|
||||
void SetZOrder(int zorder);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 添加子角色
|
||||
void AddChild(RefPtr<Node> child);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取全部子角色
|
||||
NodeList &GetAllChildren();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取全部子角色
|
||||
const NodeList &GetAllChildren() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 移除子角色
|
||||
void RemoveChild(RefPtr<Node> child);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 移除所有节点
|
||||
void RemoveAllChildren();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 从父角色移除
|
||||
void RemoveFromParent();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 暂停角色更新
|
||||
void PauseUpdating();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 继续角色更新
|
||||
void ResumeUpdating();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 角色更新是否暂停
|
||||
bool IsUpdatePausing() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 设置更新时的回调函数
|
||||
void SetCallbackOnUpdate(std::string Key, const UpdateCallback &cb);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 移除更新时的回调函数
|
||||
void RemoveCallbackOnUpdate(std::string Key);
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 判断点是否在角色内
|
||||
virtual bool ContainsPoint(const glm::vec2 &point) const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 将世界坐标系点转换为局部坐标系点
|
||||
glm::vec2 ConvertToLocal(const glm::vec2 &point) const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 将局部坐标系点转换为世界坐标系点
|
||||
glm::vec2 ConvertToWorld(const glm::vec2 &point) const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 渲染角色边界
|
||||
void ShowBorder(bool show);
|
||||
|
||||
|
||||
public:
|
||||
Node(/* args */);
|
||||
~Node();
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 更新自己的二维变换,并通知所有子角色
|
||||
void UpdateTransform() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 向上追溯更新
|
||||
/// @details 对于节点树 A->B(dirty)->C->D,当对 D 执行 UpdateTransformUpwards 时会对 B、C、D 从上到下依次更新
|
||||
void UpdateTransformUpwards() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取二维变换矩阵
|
||||
const Matrix3x2 &GetTransformMatrix() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取二维变换的逆矩阵
|
||||
const Matrix3x2 &GetTransformInverseMatrix() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 获取变换到父角色的二维变换矩阵
|
||||
const Matrix3x2 &GetTransformMatrixToParent() const;
|
||||
|
||||
/// \~chinese
|
||||
/// @brief 将所有子角色按Z轴顺序排序
|
||||
void Reorder();
|
||||
|
||||
enum DirtyFlag : uint8_t
|
||||
{
|
||||
Clean = 0,
|
||||
DirtyTransform = 1,
|
||||
DirtyTransformInverse = 1 << 1,
|
||||
DirtyOpacity = 1 << 2,
|
||||
DirtyVisibility = 1 << 3
|
||||
};
|
||||
};
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "Asset/AssetManager.h"
|
||||
#include "Asset/Asset_Script.h"
|
||||
#include "Tool/Math.h"
|
||||
#include "EngineFrame/Actor/Actor.h"
|
||||
#include "EngineFrame/Base/Actor.h"
|
||||
#include "EngineCore/Game.h"
|
||||
|
||||
Animation::Animation()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "EngineFrame/Actor/Actor.h"
|
||||
#include "EngineFrame/Base/Actor.h"
|
||||
#include "EngineFrame/Component/Sprite.h"
|
||||
#include "Asset/AnimationStruct.h"
|
||||
#include <functional>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
#include "EngineFrame/Actor/Actor.h"
|
||||
#include "EngineFrame/Base/Actor.h"
|
||||
#include "EngineFrame/Render/Texture.h"
|
||||
#include "EngineFrame/Component/Sprite.h"
|
||||
class Canvas : public Actor
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#include "Component.h"
|
||||
#include "EngineFrame/Actor/Actor.h"
|
||||
|
||||
void Component::Init()
|
||||
{
|
||||
addTag(Tag::COMPONENT);
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
#pragma once
|
||||
#include "EngineFrame/Base/BaseNode.h"
|
||||
|
||||
#include <SDL.h>
|
||||
class Actor;
|
||||
class Component : public BaseNode
|
||||
{
|
||||
|
||||
public:
|
||||
void Init() override;
|
||||
};
|
||||
@@ -1,13 +1,6 @@
|
||||
#include "RenderBase.h"
|
||||
#include "EngineFrame/Actor/Actor.h"
|
||||
#include "EngineFrame/Base/Actor.h"
|
||||
|
||||
RenderBase::RenderBase()
|
||||
{
|
||||
}
|
||||
|
||||
RenderBase::~RenderBase()
|
||||
{
|
||||
}
|
||||
|
||||
void RenderBase::CalcRenderInfo()
|
||||
{
|
||||
@@ -16,39 +9,23 @@ void RenderBase::CalcRenderInfo()
|
||||
|
||||
void RenderBase::Init()
|
||||
{
|
||||
Component::Init();
|
||||
// 标记该组件需要渲染和更新
|
||||
addTag(Tag::RENDER);
|
||||
addTag(Tag::UPDATE);
|
||||
addTag(Tag::TRANSFORM);
|
||||
// 计算渲染信息
|
||||
CalcRenderInfo();
|
||||
}
|
||||
|
||||
void RenderBase::Update(float deltaTime)
|
||||
{
|
||||
if (!Visible)
|
||||
return;
|
||||
Component::Update(deltaTime);
|
||||
|
||||
}
|
||||
|
||||
void RenderBase::Render()
|
||||
{
|
||||
if (!Visible)
|
||||
return;
|
||||
Component::Render();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RenderBase::SetIterationPos(Vec2 pos)
|
||||
{
|
||||
Component::SetIterationPos(pos);
|
||||
Actor::SetIterationPos(pos);
|
||||
CalcRenderInfo(); // 更新渲染信息
|
||||
}
|
||||
|
||||
void RenderBase::SetIterationScale(Vec2 scale)
|
||||
{
|
||||
Component::SetIterationScale(scale);
|
||||
Actor::SetIterationScale(scale);
|
||||
CalcRenderInfo(); // 更新渲染信息
|
||||
}
|
||||
|
||||
@@ -56,31 +33,31 @@ void RenderBase::SetIterationRotation(float angle)
|
||||
{
|
||||
if (!Visible)
|
||||
return;
|
||||
Component::SetIterationRotation(angle);
|
||||
Actor::SetIterationRotation(angle);
|
||||
CalcRenderInfo(); // 更新渲染信息
|
||||
}
|
||||
|
||||
void RenderBase::SetPos(Vec2 pos)
|
||||
{
|
||||
Component::SetPos(pos);
|
||||
Actor::SetPos(pos);
|
||||
|
||||
CalcRenderInfo(); // 更新渲染信息
|
||||
}
|
||||
|
||||
void RenderBase::SetScale(Vec2 scale)
|
||||
{
|
||||
Component::SetScale(scale);
|
||||
Actor::SetScale(scale);
|
||||
CalcRenderInfo(); // 更新渲染信息
|
||||
}
|
||||
|
||||
void RenderBase::SetRotation(float angle)
|
||||
{
|
||||
Component::SetRotation(angle);
|
||||
Actor::SetRotation(angle);
|
||||
CalcRenderInfo(); // 更新渲染信息
|
||||
}
|
||||
|
||||
void RenderBase::SetAnchor(Vec2 anchor)
|
||||
{
|
||||
Component::SetAnchor(anchor);
|
||||
Actor::SetAnchor(anchor);
|
||||
CalcRenderInfo(); // 更新渲染信息
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#pragma once
|
||||
#include "EngineFrame/Base/Actor.h"
|
||||
|
||||
#include "EngineFrame/Component/Component.h"
|
||||
|
||||
class RenderBase : public Component
|
||||
class RenderBase : public Actor
|
||||
{
|
||||
|
||||
public:
|
||||
@@ -19,21 +18,11 @@ public:
|
||||
bool Visible = true;
|
||||
// 是否在屏幕内
|
||||
bool IsInScreen = false;
|
||||
//渲染矩阵
|
||||
GlMatrix RenderMatrix;
|
||||
};
|
||||
|
||||
public:
|
||||
RenderBase(/* args */);
|
||||
~RenderBase();
|
||||
|
||||
public:
|
||||
void Init() override;
|
||||
|
||||
void Update(float deltaTime) override;
|
||||
void Render() override;
|
||||
|
||||
public:
|
||||
public:
|
||||
// 设置迭代的坐标
|
||||
void SetIterationPos(Vec2 pos) override;
|
||||
|
||||
@@ -43,35 +43,6 @@ RefPtr<Texture> Sprite::GetTexture()
|
||||
return m_texture;
|
||||
}
|
||||
|
||||
GlMatrix Sprite::matrix3x2ToGLMatrix(const Matrix3x2 &mat)
|
||||
{
|
||||
return {
|
||||
// 列0:x轴线性变换
|
||||
mat._11, // [0][0]
|
||||
mat._12, // [1][0]
|
||||
0.0f, // [2][0]
|
||||
0.0f, // [3][0]
|
||||
|
||||
// 列1:y轴线性变换
|
||||
mat._21, // [0][1]
|
||||
mat._22, // [1][1]
|
||||
0.0f, // [2][1]
|
||||
0.0f, // [3][1]
|
||||
|
||||
// 列2:z轴(固定)
|
||||
0.0f, // [0][2]
|
||||
0.0f, // [1][2]
|
||||
1.0f, // [2][2]
|
||||
0.0f, // [3][2]
|
||||
|
||||
// 列3:平移
|
||||
mat._31, // [0][3](x平移)
|
||||
mat._32, // [1][3](y平移)
|
||||
0.0f, // [2][3]
|
||||
1.0f // [3][3]
|
||||
};
|
||||
}
|
||||
|
||||
void Sprite::CalcRenderInfoLogic()
|
||||
{
|
||||
// 获取至在最终的父对象检查是否显示
|
||||
@@ -105,8 +76,8 @@ void Sprite::CalcRenderInfoLogic()
|
||||
// 纹理数据里带的偏移数据 有这个偏移才能保证动画播放时视觉中心点在一个点上
|
||||
auto T_Size = m_texture->getSize();
|
||||
auto T_Pos = m_texture->getPos();
|
||||
float texturePosX = flipX ? -(T_Size.width + T_Pos.x) + SDL_abs(transform.position.x * 2) : T_Pos.x;
|
||||
float texturePosY = flipY ? -(T_Size.height + T_Pos.y) + SDL_abs(transform.position.y * 2) : T_Pos.y;
|
||||
float texturePosX = flipX ? -((float)T_Size.width + (float)T_Pos.x) + SDL_fabsf(transform.position.x * 2.0f) : (float)T_Pos.x;
|
||||
float texturePosY = flipY ? -((float)T_Size.height + (float)T_Pos.y) + SDL_fabsf(transform.position.y * 2.0f) : (float)T_Pos.y;
|
||||
|
||||
// 先计算Img坐标与精灵坐标合成后的真实坐标
|
||||
float RealPosX = transform.position.x + texturePosX;
|
||||
@@ -117,22 +88,22 @@ void Sprite::CalcRenderInfoLogic()
|
||||
float baseY = transformIter.position.y + RealPosY;
|
||||
|
||||
// 获取当前帧的原始尺寸
|
||||
int frameWidth = Size.width;
|
||||
int frameHeight = Size.height;
|
||||
float frameWidth = (float)Size.width;
|
||||
float frameHeight = (float)Size.height;
|
||||
|
||||
// 原始锚点偏移(基于帧尺寸)
|
||||
float origAnchorOffsetX = int(frameWidth * Anchor.x);
|
||||
float origAnchorOffsetY = int(frameHeight * Anchor.y);
|
||||
float origAnchorOffsetX = frameWidth * Anchor.x;
|
||||
float origAnchorOffsetY = frameHeight * Anchor.y;
|
||||
|
||||
// 缩放的绝对值
|
||||
float absScaleX = SDL_fabs(scaleX);
|
||||
float absScaleY = SDL_fabs(scaleY);
|
||||
float absScaleX = SDL_fabsf(scaleX);
|
||||
float absScaleY = SDL_fabsf(scaleY);
|
||||
// 缩放后的尺寸
|
||||
float scaledWidth = frameWidth * absScaleX;
|
||||
float scaledHeight = frameHeight * absScaleY;
|
||||
// 缩放后的锚点偏移
|
||||
float scaledAnchorOffsetX = int(origAnchorOffsetX * absScaleX);
|
||||
float scaledAnchorOffsetY = int(origAnchorOffsetY * absScaleY);
|
||||
float scaledAnchorOffsetX = origAnchorOffsetX * absScaleX;
|
||||
float scaledAnchorOffsetY = origAnchorOffsetY * absScaleY;
|
||||
|
||||
// 计算缩放后的锚点偏移与原锚点偏移的差值
|
||||
float scaleOffsetX = scaledAnchorOffsetX - origAnchorOffsetX;
|
||||
@@ -142,9 +113,6 @@ void Sprite::CalcRenderInfoLogic()
|
||||
float Xpos = baseX - scaleOffsetX;
|
||||
float Ypos = baseY - scaleOffsetY;
|
||||
|
||||
Xpos = (int)Xpos; // 强制转换为整数
|
||||
Ypos = (int)Ypos; // 强制转换为整数
|
||||
|
||||
// 更新渲染信息
|
||||
_RenderGuidanceInfo.rect = {Xpos, Ypos, scaledWidth, scaledHeight};
|
||||
_RenderGuidanceInfo.AnchorPos = {scaledAnchorOffsetX, scaledAnchorOffsetY};
|
||||
@@ -152,8 +120,8 @@ void Sprite::CalcRenderInfoLogic()
|
||||
m_texture->setAlpha(this->Alpha);
|
||||
|
||||
// 屏幕内检测
|
||||
int screenWidth = Game::GetInstance().Screen_W;
|
||||
int screenHeight = Game::GetInstance().Screen_H;
|
||||
float screenWidth = (float)Game::GetInstance().Screen_W;
|
||||
float screenHeight = (float)Game::GetInstance().Screen_H;
|
||||
bool isInScreen = (Xpos + scaledWidth >= 0 && Xpos <= screenWidth && Ypos + scaledHeight >= 0 && Ypos <= screenHeight);
|
||||
_RenderGuidanceInfo.IsInScreen = isInScreen;
|
||||
|
||||
|
||||
@@ -33,10 +33,6 @@ public:
|
||||
std::string imgPath;
|
||||
int Index;
|
||||
|
||||
Matrix3x2 transform_matrix_;
|
||||
|
||||
GlMatrix matrix3x2ToGLMatrix(const Matrix3x2 &mat);
|
||||
|
||||
public:
|
||||
// 计算渲染信息
|
||||
void CalcRenderInfoLogic();
|
||||
|
||||
@@ -10,7 +10,7 @@ public:
|
||||
~Text();
|
||||
|
||||
// 显式引入基类的Init方法,避免隐藏
|
||||
using Component::Init;
|
||||
using Actor::Init;
|
||||
void Init(std::string Str, TTF_Font *font, SDL_Color color);
|
||||
void Render() override;
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ RenderManager::RenderManager(SDL_Window *window)
|
||||
_windowHeight = height;
|
||||
|
||||
// 游戏的初始正交投影矩阵
|
||||
_GameOrthoMatrix = glm::ortho(0.0f, (float)width / 1.2f, (float)height / 1.2f, 0.0f, -1.0f, 1.0f);
|
||||
_GameOrthoMatrix = glm::ortho(0.0f, (float)width, (float)height, 0.0f, -1.0f, 1.0f);
|
||||
// UI的初始正交投影矩阵
|
||||
_UIOrthoMatrix = glm::ortho(0.0f, (float)width, (float)height, 0.0f, -1.0f, 1.0f);
|
||||
|
||||
@@ -36,6 +36,7 @@ RenderManager::RenderManager(SDL_Window *window)
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
// 启用混合模式
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
// 默认设置标准alpha混合
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
@@ -228,8 +229,8 @@ void RenderManager::Init2DTextureProgram()
|
||||
glUniform1i(_currentRenderParams.UnimLocs[2], 0);
|
||||
|
||||
// 处理纹理裁剪
|
||||
int texWidth = textureObj->getSize().width;
|
||||
int texHeight = textureObj->getSize().height;
|
||||
float texWidth = (float)textureObj->getSize().width;
|
||||
float texHeight = (float)textureObj->getSize().height;
|
||||
|
||||
// 计算纹理坐标
|
||||
float minu, minv, maxu, maxv;
|
||||
@@ -336,6 +337,16 @@ void RenderManager::SetOrthoMatrixType(int type)
|
||||
_OrthoMatrix = _UIOrthoMatrix;
|
||||
}
|
||||
|
||||
glm::mat4 RenderManager::GetOrthoMatrix()
|
||||
{
|
||||
return _OrthoMatrix;
|
||||
}
|
||||
|
||||
void RenderManager::SetOrthoMatrix(glm::mat4 matrix)
|
||||
{
|
||||
_OrthoMatrix = matrix;
|
||||
}
|
||||
|
||||
GLuint RenderManager::CompileShader(GLenum type, std::string Path)
|
||||
{
|
||||
std::ifstream Source("shader/" + Path);
|
||||
|
||||
@@ -78,6 +78,11 @@ public:
|
||||
void DrawTexture(RefPtr<Texture> texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip, void *userdata = nullptr);
|
||||
// 设置正交投影矩阵类型
|
||||
void SetOrthoMatrixType(int type);
|
||||
// 获取渲染的正交投影矩阵
|
||||
glm::mat4 GetOrthoMatrix();
|
||||
// 设置渲染的正交投影矩阵
|
||||
void SetOrthoMatrix(glm::mat4 matrix);
|
||||
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@@ -32,8 +32,9 @@ bool Texture::Init(std::string PngPath)
|
||||
glBindTexture(GL_TEXTURE_2D, m_TextureID);
|
||||
|
||||
// 环绕方式
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
// 对2D纹理设置环绕模式(S=X轴,T=Y轴)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// 缩小过滤:使用最近邻采样
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
// 放大过滤:使用最近邻采样
|
||||
@@ -100,8 +101,9 @@ bool Texture::Init(std::string ImgPath, int Index)
|
||||
|
||||
// 设置纹理参数(保持与原有SDL纹理相同的采样模式)
|
||||
// 环绕方式:重复
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
// 对2D纹理设置环绕模式(S=X轴,T=Y轴)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// 过滤方式:最近邻(与SDL_ScaleModeNearest对应)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
@@ -139,8 +141,9 @@ bool Texture::Init(SDL_Surface *rgbaSurface)
|
||||
glBindTexture(GL_TEXTURE_2D, m_TextureID);
|
||||
|
||||
// 环绕方式
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
// 对2D纹理设置环绕模式(S=X轴,T=Y轴)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// 缩小过滤:使用最近邻采样
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
// 放大过滤:使用最近邻采样
|
||||
@@ -192,8 +195,9 @@ bool Texture::Init(VecSize size)
|
||||
m_FrameSize = size;
|
||||
|
||||
// 环绕方式
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
// 对2D纹理设置环绕模式(S=X轴,T=Y轴)
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// 缩小过滤:使用最近邻采样
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
// 放大过滤:使用最近邻采样
|
||||
|
||||
Reference in New Issue
Block a user