推
This commit is contained in:
@@ -27,8 +27,6 @@ Animation::~Animation()
|
||||
|
||||
void Animation::Init(std::string AniPath)
|
||||
{
|
||||
Actor::Init();
|
||||
|
||||
AniScriptParser::AniInfo Info = AssetManager::GetInstance().StructAniInfo(AniPath);
|
||||
this->AniPath = AniPath;
|
||||
this->AnimationFlag = Info.Flag;
|
||||
@@ -45,17 +43,19 @@ void Animation::Init(std::string AniPath)
|
||||
FrameObj.Img_Path = AdditionalOptions(FrameObj.Img_Path, this->AdditionalOptionsData);
|
||||
}
|
||||
SpriteObj = new Sprite(FrameObj.Img_Path, FrameObj.Img_Index);
|
||||
SpriteObj->SetAnchor(Vec2(0.5f, 0.5f));
|
||||
SpriteObj->SetPos(Vec2(FrameObj.Img_Pos.x, FrameObj.Img_Pos.y));
|
||||
SpriteObj->SetPosition(FrameObj.Img_Pos.x, FrameObj.Img_Pos.y);
|
||||
SpriteObj->SetVisible(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
SpriteObj = new Sprite();
|
||||
SpriteObj->SetVisible(false);
|
||||
SDL_Log("Animation::Init() SpriteObj is nullptr");
|
||||
}
|
||||
SpriteArr.push_back(SpriteObj);
|
||||
//记录最大帧宽高
|
||||
auto SpriteSize = SpriteObj->GetSize();
|
||||
if(this->MaxSize.width < SpriteSize.width)this->MaxSize.width = SpriteSize.width;
|
||||
if(this->MaxSize.height < SpriteSize.height)this->MaxSize.height = SpriteSize.height;
|
||||
AddChild(SpriteObj);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ void Animation::Init(std::string AniPath)
|
||||
for (auto &Ani : Info.AniList)
|
||||
{
|
||||
RefPtr<Animation> AlsAniObj = new Animation(Dir + Ani.second.path);
|
||||
AlsAniObj->SetRenderZOrder(Ani.second.layer[1]);
|
||||
AlsAniObj->SetZOrder(Ani.second.layer[1]);
|
||||
AddChild(AlsAniObj);
|
||||
}
|
||||
}
|
||||
@@ -84,20 +84,16 @@ void Animation::Init(std::string AniPath)
|
||||
FlushFrame(0);
|
||||
}
|
||||
|
||||
void Animation::HandleEvents(SDL_Event *e)
|
||||
{
|
||||
}
|
||||
|
||||
void Animation::Update(float deltaTime)
|
||||
void Animation::OnUpdate(float deltaTime)
|
||||
{
|
||||
// 可用性检查
|
||||
if (IsUsability && Visible)
|
||||
if (IsUsability && IsVisible())
|
||||
{
|
||||
float dt_ms = deltaTime * 1000.0f;
|
||||
// 累加当前帧时间
|
||||
CurrentIndexT += dt_ms;
|
||||
// 插值模式判断
|
||||
InterpolationLogic();
|
||||
// InterpolationLogic();
|
||||
|
||||
// 循环处理:只要当前时间超过帧延迟,就切换帧(支持一次跳过多帧)
|
||||
while (CurrentIndexT >= NextFrameDelay)
|
||||
@@ -127,32 +123,26 @@ void Animation::Update(float deltaTime)
|
||||
}
|
||||
}
|
||||
}
|
||||
Actor::Update(deltaTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto &Sp : SpriteArr)
|
||||
{
|
||||
Sp->SetVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Animation::Render()
|
||||
void Animation::OnAdded(Actor *node)
|
||||
{
|
||||
Actor::Render();
|
||||
}
|
||||
|
||||
void Animation::OnAdded(BaseNode *node)
|
||||
{
|
||||
Actor::OnAdded(node);
|
||||
FlushFrame(0);
|
||||
}
|
||||
|
||||
void Animation::Clear()
|
||||
{
|
||||
}
|
||||
|
||||
void Animation::SetVisible(bool visible)
|
||||
{
|
||||
// 设置启用的时候要更新一下当前帧的渲染信息 避免因为延迟造成的坐标闪烁
|
||||
if (visible)
|
||||
{
|
||||
CurrentFrame->CalcRenderInfoLogic();
|
||||
CurrentFrame->CalcRenderInfo();
|
||||
CurrentFrame->SetVisible(true);
|
||||
}
|
||||
Actor::SetVisible(visible);
|
||||
}
|
||||
@@ -192,7 +182,8 @@ void Animation::FlushFrame(int Index)
|
||||
if (FlagBuf.count("IMAGE_RATE"))
|
||||
{
|
||||
Vec2 Rate = std::get<Vec2>(FlagBuf["IMAGE_RATE"]);
|
||||
CurrentFrame->SetScale(Vec2{Rate.x, Rate.y});
|
||||
CurrentFrame->SetScale(Rate.x, Rate.y);
|
||||
CurrentFrame->SetPosition(FrameInfo.Img_Pos.x * Rate.x, FrameInfo.Img_Pos.y * Rate.y);
|
||||
}
|
||||
// 线性减淡
|
||||
if (FlagBuf.count("GRAPHIC_EFFECT_LINEARDODGE"))
|
||||
@@ -202,7 +193,7 @@ void Animation::FlushFrame(int Index)
|
||||
// 旋转
|
||||
if (FlagBuf.count("IMAGE_ROTATE"))
|
||||
{
|
||||
CurrentFrame->SetAnchor(Vec2{0.5f, 0.5f});
|
||||
// CurrentFrame->SetAnchor(0.5f, 0.5f);
|
||||
CurrentFrame->SetRotation(std::get<float>(FlagBuf["IMAGE_ROTATE"]));
|
||||
}
|
||||
// 染色
|
||||
@@ -277,10 +268,10 @@ void Animation::InterpolationLogic()
|
||||
}
|
||||
// 坐标
|
||||
{
|
||||
Vec2 PosData = {
|
||||
glm::vec2 PosData = {
|
||||
(OldData.Img_Pos.x + (NewData.Img_Pos.x - OldData.Img_Pos.x) * InterRate),
|
||||
(OldData.Img_Pos.y + (NewData.Img_Pos.y - OldData.Img_Pos.y) * InterRate)};
|
||||
CurrentFrame->SetPos(PosData);
|
||||
CurrentFrame->SetPosition(PosData);
|
||||
}
|
||||
// 缩放
|
||||
{
|
||||
@@ -294,10 +285,9 @@ void Animation::InterpolationLogic()
|
||||
{
|
||||
NewRateData = std::get<Vec2>(NewData.Flag["IMAGE_RATE"]);
|
||||
}
|
||||
Vec2 RateData = {
|
||||
glm::vec2 RateData = {
|
||||
OldRateData.x + (NewRateData.x - OldRateData.x) * InterRate,
|
||||
OldRateData.y + (NewRateData.y - OldRateData.y) * InterRate};
|
||||
CurrentFrame->SetAnchor(Vec2{0.5f, 0.5f});
|
||||
CurrentFrame->SetScale(RateData);
|
||||
}
|
||||
// 旋转
|
||||
@@ -315,3 +305,8 @@ void Animation::InterpolationLogic()
|
||||
CurrentFrame->SetRotation(OldAngleData + (NewAngleData - OldAngleData) * InterRate);
|
||||
}
|
||||
}
|
||||
|
||||
VecSize Animation::GetMaxSize()
|
||||
{
|
||||
return MaxSize;
|
||||
}
|
||||
|
||||
@@ -24,24 +24,26 @@ public:
|
||||
Animation(std::string AniPath, std::function<std::string(std::string, Animation::ReplaceData)> AdditionalOptions, Animation::ReplaceData);
|
||||
~Animation();
|
||||
|
||||
/**初始化 */
|
||||
void Init(std::string AniPath);
|
||||
void HandleEvents(SDL_Event *e) override;
|
||||
void Update(float deltaTime) override;
|
||||
void Render() override;
|
||||
void OnAdded(BaseNode *node) override;
|
||||
void Clear() override;
|
||||
|
||||
void OnUpdate(float deltaTime) override;
|
||||
void OnAdded(Actor *node) override;
|
||||
void SetVisible(bool visible) override;
|
||||
|
||||
public:
|
||||
/**刷新帧 */
|
||||
void FlushFrame(int Index);
|
||||
/**重置Ani */
|
||||
void Reset();
|
||||
/**获取当前帧信息 */
|
||||
AniScriptParser::AniFrame GetCurrentFrameInfo();
|
||||
// 设置帧索引
|
||||
void SetFrameIndex(int Index);
|
||||
void InterpolationLogic();
|
||||
// TODO SetOutline
|
||||
// TODO SetDye
|
||||
// TODO SetCrop
|
||||
|
||||
/**获取最大尺寸 */
|
||||
VecSize GetMaxSize();
|
||||
|
||||
public:
|
||||
// Ani是否可用
|
||||
@@ -76,20 +78,11 @@ public:
|
||||
std::string AniPath;
|
||||
// 是否描边
|
||||
bool IsOutline = false;
|
||||
// // 描边颜色
|
||||
// OutlineColor = null;
|
||||
// // 描边对象List
|
||||
// OutlineList = null;
|
||||
// // 当前描边对象
|
||||
// CurrentOutline = null;
|
||||
// // 染色颜色
|
||||
// DyeColor = null;
|
||||
// // 染色帧List
|
||||
// DyeFrameList = null;
|
||||
// // 整体染色
|
||||
// DyeAllFlag = false;
|
||||
|
||||
// 附加选项
|
||||
std::function<std::string(std::string, Animation::ReplaceData)> AdditionalOptions;
|
||||
Animation::ReplaceData AdditionalOptionsData;
|
||||
/**最大尺寸
|
||||
* 所有子精灵最大的尺寸
|
||||
*/
|
||||
VecSize MaxSize = {0, 0};
|
||||
};
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
#include "AnimationManager.h"
|
||||
#include "EngineCore/Game.h"
|
||||
|
||||
AnimationManager::AnimationManager()
|
||||
{
|
||||
}
|
||||
|
||||
void AnimationManager::PreRender()
|
||||
{
|
||||
Actor::PreRender();
|
||||
// 标记是否是第一个子对象(用于初始化min/max值)
|
||||
bool isFirst = true;
|
||||
float minX = 0.0f, minY = 0.0f; // 所有子对象的最小X、Y坐标
|
||||
float maxX = 0.0f, maxY = 0.0f; // 所有子对象的最大X、Y坐标(右下角)
|
||||
|
||||
RefPtr<BaseNode> child = m_BaseNodes.GetFirst();
|
||||
while (child)
|
||||
{
|
||||
// 转换为Animation对象
|
||||
Animation *ani = static_cast<Animation *>(child.Get());
|
||||
|
||||
float width = ani->CurrentFrame->_RenderGuidanceInfo.rect.w;
|
||||
float height = ani->CurrentFrame->_RenderGuidanceInfo.rect.h;
|
||||
float x = ani->CurrentFrame->_RenderGuidanceInfo.rect.x;
|
||||
float y = ani->CurrentFrame->_RenderGuidanceInfo.rect.y;
|
||||
|
||||
// 计算子对象的右下角坐标(左上角 + 宽高)
|
||||
float currentMaxX = x + width;
|
||||
float currentMaxY = y + height;
|
||||
// 初始化或更新min/max值
|
||||
if (isFirst)
|
||||
{
|
||||
minX = x;
|
||||
minY = y;
|
||||
maxX = currentMaxX;
|
||||
maxY = currentMaxY;
|
||||
isFirst = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
minX = std::min(minX, x);
|
||||
minY = std::min(minY, y);
|
||||
maxX = std::max(maxX, currentMaxX);
|
||||
maxY = std::max(maxY, currentMaxY);
|
||||
}
|
||||
|
||||
child = child->GetNext();
|
||||
}
|
||||
// 计算最终的包围盒矩形
|
||||
if (!isFirst) // 至少有一个子对象时才计算
|
||||
{
|
||||
m_RenderRect.x = minX; // 矩形左上角X
|
||||
m_RenderRect.y = minY; // 矩形左上角Y
|
||||
m_RenderRect.w = maxX - minX; // 矩形宽度(右下角X - 左上角X)
|
||||
m_RenderRect.h = maxY - minY; // 矩形高度(右下角Y - 左上角Y)
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationManager::Render()
|
||||
{
|
||||
Actor::Render();
|
||||
}
|
||||
|
||||
void AnimationManager::AddAnimation(RefPtr<Animation> ani)
|
||||
{
|
||||
this->AddChild(ani);
|
||||
}
|
||||
|
||||
void AnimationManager::Clear()
|
||||
{
|
||||
this->RemoveAllChild();
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#pragma once
|
||||
#include "EngineFrame/Component/Animation.h"
|
||||
#include <vector>
|
||||
class AnimationManager : public Actor
|
||||
{
|
||||
private:
|
||||
SDL_Texture *m_Texture = nullptr;
|
||||
SDL_FRect m_RenderRect = {0, 0, 0, 0};
|
||||
|
||||
public:
|
||||
AnimationManager();
|
||||
// void Update(float deltaTime) override;
|
||||
void PreRender() override;
|
||||
void Render() override;
|
||||
|
||||
public:
|
||||
// 添加Ani
|
||||
void AddAnimation(RefPtr<Animation> ani);
|
||||
// 清空Ani
|
||||
void Clear();
|
||||
};
|
||||
132
source/EngineFrame/Component/AnimationMap.cpp
Normal file
132
source/EngineFrame/Component/AnimationMap.cpp
Normal file
@@ -0,0 +1,132 @@
|
||||
#include "AnimationMap.h"
|
||||
#include "EngineCore/Game.h"
|
||||
#include "EngineFrame/Render/RenderManager.h"
|
||||
AnimationMap::~AnimationMap()
|
||||
{
|
||||
}
|
||||
|
||||
void AnimationMap::CompleteConstruction()
|
||||
{
|
||||
m_size = {800, 600};
|
||||
// 遍历自己的所持有的所有Ani 取最大的尺寸
|
||||
auto &ac = this->GetAllChildren();
|
||||
RefPtr<Node> child = ac.GetFirst();
|
||||
while (child)
|
||||
{
|
||||
Animation *anim = static_cast<Animation *>(child.Get());
|
||||
auto size = anim->GetMaxSize();
|
||||
if (size.width > m_size.width)
|
||||
m_size.width = size.width;
|
||||
if (size.height > m_size.height)
|
||||
m_size.height = size.height;
|
||||
child = child->GetNext();
|
||||
}
|
||||
|
||||
SetSize(m_size);
|
||||
// 创建指定大小的纹理
|
||||
m_texture = new Texture();
|
||||
m_texture->Init(m_size);
|
||||
|
||||
// 构造FBO
|
||||
glGenFramebuffers(1, &m_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
// 将目标纹理附加到FBO的颜色附着点
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER, // 帧缓冲类型
|
||||
GL_COLOR_ATTACHMENT0, // 颜色附着点(可多个,这里用第一个)
|
||||
GL_TEXTURE_2D, // 纹理类型
|
||||
m_texture->getID(), // 目标纹理ID
|
||||
0 // 多级渐远纹理级别
|
||||
);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0); // 解绑FBO
|
||||
}
|
||||
|
||||
void AnimationMap::AddAnimation(RefPtr<Animation> animation)
|
||||
{
|
||||
this->AddChild(animation);
|
||||
}
|
||||
|
||||
void AnimationMap::Reset()
|
||||
{
|
||||
auto &ac = this->GetAllChildren();
|
||||
RefPtr<Node> child = ac.GetFirst();
|
||||
while (child)
|
||||
{
|
||||
Animation *anim = static_cast<Animation *>(child.Get());
|
||||
anim->Reset();
|
||||
child = child->GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
void AnimationMap::Render()
|
||||
{
|
||||
Actor::PreRender();
|
||||
Actor::PrepareToRender();
|
||||
Actor::OnRender();
|
||||
}
|
||||
|
||||
void AnimationMap::OnRender()
|
||||
{
|
||||
RenderManager *renderer = Game::GetInstance().GetRenderer();
|
||||
renderer->DrawTexture(m_texture);
|
||||
}
|
||||
|
||||
void AnimationMap::OnUpdate(float deltaTime)
|
||||
{
|
||||
Actor::OnUpdate(deltaTime);
|
||||
|
||||
RenderManager *renderer = Game::GetInstance().GetRenderer();
|
||||
// 绑定FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
// 清屏
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
// 保存原始的正交矩阵 设置纹理对应的正交矩阵 和 视口
|
||||
Oom = renderer->GetOrthoMatrix();
|
||||
renderer->SetOrthoMatrix(glm::ortho(0.0f, (float)m_size.width, 0.0f, (float)m_size.height, -1.0f, 1.0f));
|
||||
Oviewport = renderer->GetViewport();
|
||||
renderer->SetViewport({0, 0, m_size.width, m_size.height});
|
||||
// 以上步骤将渲染目标调整至AniMap的纹理上
|
||||
|
||||
SDL_Rect buf;
|
||||
buf.x = 0;
|
||||
buf.y = 0;
|
||||
buf.w = m_size.width;
|
||||
buf.h = m_size.height;
|
||||
glm::vec4 red = {0.0f, 0.0f, 1.0f, 0.4f}; // RGBA:红色,不透明基础色
|
||||
Game::GetInstance().GetRenderer()->DrawRect(&buf, red);
|
||||
|
||||
auto &ac = this->GetAllChildren();
|
||||
RefPtr<Node> child = ac.GetFirst();
|
||||
while (child)
|
||||
{
|
||||
child->Render();
|
||||
child = child->GetNext();
|
||||
}
|
||||
|
||||
// 渲染完毕后,将渲染目标恢复为默认
|
||||
// 解绑FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
// 恢复原始的正交矩阵 和 视口
|
||||
renderer->SetOrthoMatrix(Oom);
|
||||
renderer->SetViewport(Oviewport);
|
||||
|
||||
Actor::OnUpdate(deltaTime);
|
||||
}
|
||||
|
||||
// void AnimationMap::SetVisible(bool visible)
|
||||
// {
|
||||
// if (this->IsVisible() == visible)
|
||||
// return;
|
||||
// Actor::SetVisible(visible);
|
||||
// auto ac = this->GetAllChildren();
|
||||
// RefPtr<Node> next;
|
||||
// for (RefPtr<Node> child = ac.GetFirst(); child; child = next)
|
||||
// {
|
||||
// next = child->GetNext();
|
||||
// child->SetVisible(visible);
|
||||
// }
|
||||
// }
|
||||
|
||||
AnimationMap::AnimationMap()
|
||||
{
|
||||
}
|
||||
36
source/EngineFrame/Component/AnimationMap.h
Normal file
36
source/EngineFrame/Component/AnimationMap.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
#include "EngineFrame/Base/Actor.h"
|
||||
#include "Animation.h"
|
||||
class AnimationMap : public Actor
|
||||
{
|
||||
private:
|
||||
/**纹理 */
|
||||
RefPtr<Texture> m_texture = nullptr;
|
||||
/**FBO */
|
||||
GLuint m_fbo = 0;
|
||||
/**大小 */
|
||||
VecSize m_size;
|
||||
/**原始的正交矩阵 */
|
||||
glm::mat4 Oom;
|
||||
/**原始的视口 */
|
||||
SDL_Rect Oviewport;
|
||||
|
||||
public:
|
||||
AnimationMap(/* args */);
|
||||
~AnimationMap();
|
||||
|
||||
/**完成构造
|
||||
* 必须调用完成构造以创建足够大小的画布和各项初始化
|
||||
*/
|
||||
void CompleteConstruction();
|
||||
/**添加动画 */
|
||||
void AddAnimation(RefPtr<Animation> animation);
|
||||
|
||||
/**重置动画组 */
|
||||
void Reset();
|
||||
|
||||
void Render() override;
|
||||
void OnRender() override;
|
||||
void OnUpdate(float deltaTime) override;
|
||||
// void SetVisible(bool visible) override;
|
||||
};
|
||||
@@ -1,16 +1,29 @@
|
||||
#include "Canvas.h"
|
||||
#include "EngineCore/Game.h"
|
||||
#include "EngineFrame/Render/RenderManager.h"
|
||||
Canvas::Canvas()
|
||||
{
|
||||
|
||||
}
|
||||
Canvas::Canvas(VecSize size)
|
||||
{
|
||||
Init(size);
|
||||
}
|
||||
|
||||
Canvas::Canvas(int width, int height)
|
||||
{
|
||||
Init({width, height});
|
||||
}
|
||||
|
||||
void Canvas::Init(VecSize size)
|
||||
{
|
||||
m_size = size;
|
||||
m_renderRect = {0, 0, size.width, size.height};
|
||||
m_rect = {0, 0, (float)size.width, (float)size.height};
|
||||
SetSize(size);
|
||||
// 创建指定大小的纹理
|
||||
m_texture = new Texture();
|
||||
m_texture->Init(VecSize(Game::GetInstance().Screen_W, Game::GetInstance().Screen_H));
|
||||
|
||||
Actor::Init();
|
||||
m_texture->Init(m_size);
|
||||
|
||||
// 构造FBO
|
||||
glGenFramebuffers(1, &m_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
// 将目标纹理附加到FBO的颜色附着点
|
||||
@@ -24,92 +37,86 @@ Canvas::Canvas(VecSize size)
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0); // 解绑FBO
|
||||
}
|
||||
|
||||
void Canvas::PreRender()
|
||||
{
|
||||
m_rect.x = GetWorldPos().x;
|
||||
m_rect.y = GetWorldPos().y;
|
||||
}
|
||||
|
||||
void Canvas::Render()
|
||||
void Canvas::BeginDraw()
|
||||
{
|
||||
RenderManager *renderer = Game::GetInstance().GetRenderer();
|
||||
SDL_FPoint AnchorPos = {0, 0};
|
||||
if (m_dirty)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); // 绑定FBO
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
for (auto &info : m_drawQueue)
|
||||
{
|
||||
renderer->DrawTexture(m_imgMap[info.texture], nullptr, &info.rect, 0.f, &AnchorPos, SDL_FLIP_NONE);
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0); // 解绑FBO
|
||||
m_dirty = false;
|
||||
}
|
||||
// 绑定FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
// 清屏
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
// 保存原始的正交矩阵 设置纹理对应的正交矩阵 和 视口
|
||||
Oom = renderer->GetOrthoMatrix();
|
||||
renderer->SetOrthoMatrix(glm::ortho(0.0f, (float)m_size.width, 0.0f, (float)m_size.height, -1.0f, 1.0f));
|
||||
Oviewport = renderer->GetViewport();
|
||||
renderer->SetViewport({0, 0, m_size.width, m_size.height});
|
||||
|
||||
renderer->SetCurrentShaderProgram("flip_y");
|
||||
// 混合
|
||||
if (this->_BlendMode != NONE)
|
||||
Blend();
|
||||
renderer->DrawTexture(m_texture, &m_renderRect, &m_rect, 0.f, &AnchorPos, SDL_FLIP_NONE);
|
||||
// 还原混合
|
||||
if (this->_BlendMode != NONE)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
renderer->SetCurrentShaderProgram("normal");
|
||||
}
|
||||
|
||||
void Canvas::DrawImg(std::string img, int index, Vec2 pos)
|
||||
void Canvas::EndDraw()
|
||||
{
|
||||
m_dirty = true;
|
||||
ImgKey key = {img, index};
|
||||
DrawInfo info;
|
||||
info.rect.x = pos.x;
|
||||
info.rect.y = pos.y;
|
||||
info.texture = key;
|
||||
|
||||
if (m_imgMap.find(key) == m_imgMap.end())
|
||||
{
|
||||
RefPtr<Texture> tex = new Texture();
|
||||
tex->Init(img, index);
|
||||
m_imgMap[key] = tex;
|
||||
}
|
||||
|
||||
info.rect.w = m_imgMap[key]->getSize().width;
|
||||
info.rect.h = m_imgMap[key]->getSize().height;
|
||||
|
||||
m_drawQueue.push_back(info);
|
||||
RenderManager *renderer = Game::GetInstance().GetRenderer();
|
||||
// 解绑FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
// 恢复原始的正交矩阵 和 视口
|
||||
renderer->SetOrthoMatrix(Oom);
|
||||
renderer->SetViewport(Oviewport);
|
||||
}
|
||||
|
||||
void Canvas::DrawImg(std::string img, int index, SDL_FRect rect)
|
||||
void Canvas::DrawActor(RefPtr<Actor> actor)
|
||||
{
|
||||
m_dirty = true;
|
||||
ImgKey key = {img, index};
|
||||
DrawInfo info;
|
||||
info.rect = rect;
|
||||
info.texture = key;
|
||||
|
||||
if (m_imgMap.find(key) == m_imgMap.end())
|
||||
{
|
||||
RefPtr<Texture> tex = new Texture();
|
||||
tex->Init(img, index);
|
||||
m_imgMap[key] = tex;
|
||||
}
|
||||
|
||||
m_drawQueue.push_back(info);
|
||||
// 计算矩阵
|
||||
actor->PreRender();
|
||||
// 设定矩阵并渲染(Render中会调用OnRender)
|
||||
actor->Render();
|
||||
}
|
||||
|
||||
void Canvas::Clear()
|
||||
{
|
||||
m_drawQueue.clear();
|
||||
m_dirty = true;
|
||||
m_texture = new Texture();
|
||||
m_texture->Init(m_size);
|
||||
}
|
||||
|
||||
void Canvas::Blend()
|
||||
void Canvas::OnRender()
|
||||
{
|
||||
switch (this->_BlendMode)
|
||||
if (!m_texture || !IsVisible())
|
||||
return;
|
||||
|
||||
RenderManager *renderer = Game::GetInstance().GetRenderer();
|
||||
if (this->_BlendMode != NONE)
|
||||
{
|
||||
case LINEARDODGE:
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
|
||||
break;
|
||||
renderer->SetBlendMode(this->_BlendMode);
|
||||
}
|
||||
renderer->DrawTexture(m_texture);
|
||||
if (this->_BlendMode != NONE)
|
||||
{
|
||||
renderer->SetBlendMode(NONE);
|
||||
}
|
||||
}
|
||||
|
||||
// void Canvas::Render()
|
||||
// {
|
||||
// RenderManager *renderer = Game::GetInstance().GetRenderer();
|
||||
// SDL_FPoint AnchorPos = {0, 0};
|
||||
// if (m_dirty)
|
||||
// {
|
||||
// glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); // 绑定FBO
|
||||
// glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
// glClear(GL_COLOR_BUFFER_BIT);
|
||||
// for (auto &info : m_drawQueue)
|
||||
// {
|
||||
// renderer->DrawTexture(m_imgMap[info.texture], nullptr, &info.rect, 0.f, &AnchorPos, SDL_FLIP_NONE);
|
||||
// }
|
||||
// glBindFramebuffer(GL_FRAMEBUFFER, 0); // 解绑FBO
|
||||
// m_dirty = false;
|
||||
// }
|
||||
|
||||
// renderer->SetCurrentShaderProgram("flip_y");
|
||||
// // 混合
|
||||
// if (this->_BlendMode != NONE)
|
||||
// Blend();
|
||||
// renderer->DrawTexture(m_texture, &m_renderRect, &m_rect, 0.f, &AnchorPos, SDL_FLIP_NONE);
|
||||
// // 还原混合
|
||||
// if (this->_BlendMode != NONE)
|
||||
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
// renderer->SetCurrentShaderProgram("normal");
|
||||
// }
|
||||
|
||||
@@ -18,37 +18,37 @@ class Canvas : public Actor
|
||||
return index < other.index; // 字符串相同则比较index
|
||||
}
|
||||
};
|
||||
struct DrawInfo
|
||||
{
|
||||
ImgKey texture;
|
||||
SDL_FRect rect = {0, 0, 0, 0};
|
||||
};
|
||||
|
||||
private:
|
||||
/**纹理 */
|
||||
RefPtr<Texture> m_texture = nullptr;
|
||||
/**大小 */
|
||||
VecSize m_size;
|
||||
/**渲染大小 */
|
||||
SDL_Rect m_renderRect;
|
||||
SDL_FRect m_rect;
|
||||
/**脏标记 */
|
||||
bool m_dirty = true;
|
||||
/**FBO */
|
||||
GLuint m_fbo = 0;
|
||||
/**绘制纹理集 */
|
||||
std::map<ImgKey, RefPtr<Texture>> m_imgMap;
|
||||
/**绘制队列 */
|
||||
std::vector<DrawInfo> m_drawQueue;
|
||||
|
||||
/**原始的正交矩阵 */
|
||||
glm::mat4 Oom;
|
||||
/**原始的视口 */
|
||||
SDL_Rect Oviewport;
|
||||
|
||||
public:
|
||||
Canvas();
|
||||
Canvas(VecSize size);
|
||||
Canvas(int width, int height);
|
||||
|
||||
void PreRender() override;
|
||||
void Render() override;
|
||||
void Blend();
|
||||
/**初始化 */
|
||||
void Init(VecSize size);
|
||||
|
||||
void DrawImg(std::string img, int index, Vec2 pos);
|
||||
void DrawImg(std::string img, int index, SDL_FRect rect);
|
||||
/**开始绘制 */
|
||||
void BeginDraw();
|
||||
/**结束绘制 */
|
||||
void EndDraw();
|
||||
/**绘制角色 */
|
||||
void DrawActor(RefPtr<Actor> actor);
|
||||
/**清空画布 */
|
||||
void Clear();
|
||||
|
||||
/**重载OnRender函数 */
|
||||
void OnRender() override;
|
||||
};
|
||||
|
||||
@@ -20,7 +20,7 @@ private:
|
||||
// 数字字符纹理缓存('0'-'9'和'-')
|
||||
std::unordered_map<char, RefPtr<Texture>> m_digitTextures;
|
||||
// 当前数字的字符精灵列表
|
||||
std::vector<Sprite *> m_digitSprites;
|
||||
std::vector<Sprite *> m_digitSprites;
|
||||
|
||||
// 预加载0-9和负号的纹理
|
||||
void PreloadDigits();
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
#include "RenderBase.h"
|
||||
#include "EngineFrame/Base/Actor.h"
|
||||
|
||||
|
||||
void RenderBase::CalcRenderInfo()
|
||||
{
|
||||
this->CalcRenderInfoFlag = true;
|
||||
}
|
||||
|
||||
void RenderBase::Init()
|
||||
{
|
||||
// 计算渲染信息
|
||||
CalcRenderInfo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void RenderBase::SetIterationPos(Vec2 pos)
|
||||
{
|
||||
Actor::SetIterationPos(pos);
|
||||
CalcRenderInfo(); // 更新渲染信息
|
||||
}
|
||||
|
||||
void RenderBase::SetIterationScale(Vec2 scale)
|
||||
{
|
||||
Actor::SetIterationScale(scale);
|
||||
CalcRenderInfo(); // 更新渲染信息
|
||||
}
|
||||
|
||||
void RenderBase::SetIterationRotation(float angle)
|
||||
{
|
||||
if (!Visible)
|
||||
return;
|
||||
Actor::SetIterationRotation(angle);
|
||||
CalcRenderInfo(); // 更新渲染信息
|
||||
}
|
||||
|
||||
void RenderBase::SetPos(Vec2 pos)
|
||||
{
|
||||
Actor::SetPos(pos);
|
||||
|
||||
CalcRenderInfo(); // 更新渲染信息
|
||||
}
|
||||
|
||||
void RenderBase::SetScale(Vec2 scale)
|
||||
{
|
||||
Actor::SetScale(scale);
|
||||
CalcRenderInfo(); // 更新渲染信息
|
||||
}
|
||||
|
||||
void RenderBase::SetRotation(float angle)
|
||||
{
|
||||
Actor::SetRotation(angle);
|
||||
CalcRenderInfo(); // 更新渲染信息
|
||||
}
|
||||
|
||||
void RenderBase::SetAnchor(Vec2 anchor)
|
||||
{
|
||||
Actor::SetAnchor(anchor);
|
||||
CalcRenderInfo(); // 更新渲染信息
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
#pragma once
|
||||
#include "EngineFrame/Base/Actor.h"
|
||||
|
||||
class RenderBase : public Actor
|
||||
{
|
||||
|
||||
public:
|
||||
struct RenderGuidanceInfo
|
||||
{
|
||||
SDL_FRect rect;
|
||||
// 旋转角度
|
||||
float rotation;
|
||||
// 翻转Flag
|
||||
SDL_RendererFlip flip = SDL_FLIP_NONE;
|
||||
// 锚点坐标
|
||||
Vec2 AnchorPos;
|
||||
// 是否显示
|
||||
bool Visible = true;
|
||||
// 是否在屏幕内
|
||||
bool IsInScreen = false;
|
||||
};
|
||||
|
||||
public:
|
||||
void Init() override;
|
||||
|
||||
public:
|
||||
// 设置迭代的坐标
|
||||
void SetIterationPos(Vec2 pos) override;
|
||||
// 设置迭代的缩放
|
||||
void SetIterationScale(Vec2 scale) override;
|
||||
// 设置迭代的旋转角度
|
||||
void SetIterationRotation(float angle) override;
|
||||
|
||||
// 设置坐标
|
||||
void SetPos(Vec2 pos) override;
|
||||
// 设置缩放
|
||||
void SetScale(Vec2 scale) override;
|
||||
// 设置旋转角度
|
||||
void SetRotation(float angle) override;
|
||||
// 设置中心点
|
||||
void SetAnchor(Vec2 anchor) override;
|
||||
|
||||
// 计算渲染信息
|
||||
void CalcRenderInfo() override;
|
||||
};
|
||||
@@ -3,17 +3,31 @@
|
||||
#include "Text.h"
|
||||
#include "EngineFrame/Render/RenderManager.h"
|
||||
|
||||
void Sprite::GenerateRenderMatrix() const
|
||||
{
|
||||
Matrix3x2 RenderBuffer = Matrix3x2::Translation(glm::vec2(m_texture->getPos().x, m_texture->getPos().y)) * GetTransformMatrix();
|
||||
|
||||
// 构造OpenGl渲染矩阵
|
||||
render_matrix_ = glm::mat4(1.0f);
|
||||
// 填充旋转+缩放分量(2D 变换核心,对应 4x4 矩阵左上 2x2 区域)
|
||||
render_matrix_[0][0] = RenderBuffer[0]; // _11 → x轴缩放+旋转
|
||||
render_matrix_[0][1] = RenderBuffer[1]; // _12 → 影响y轴方向的旋转分量
|
||||
render_matrix_[1][0] = RenderBuffer[2]; // _21 → 影响x轴方向的旋转分量
|
||||
render_matrix_[1][1] = RenderBuffer[3]; // _22 → y轴缩放+旋转
|
||||
// 填充平移分量(对应 4x4 矩阵最后一行前两列,z轴平移为0)
|
||||
render_matrix_[3][0] = RenderBuffer[4]; // _31 → x方向平移(世界坐标)
|
||||
render_matrix_[3][1] = RenderBuffer[5]; // _32 → y方向平移(世界坐标)
|
||||
}
|
||||
|
||||
void Sprite::Init()
|
||||
{
|
||||
this->Size = m_texture->getSize();
|
||||
RenderBase::Init();
|
||||
SetSize(m_texture->getSize());
|
||||
}
|
||||
|
||||
void Sprite::SetTexture(RefPtr<Texture> texture)
|
||||
{
|
||||
m_texture = texture;
|
||||
Init();
|
||||
CalcRenderInfoLogic(); // 第一次计算
|
||||
}
|
||||
|
||||
Sprite::Sprite(std::string imgPath, int Index)
|
||||
@@ -23,7 +37,6 @@ Sprite::Sprite(std::string imgPath, int Index)
|
||||
m_texture = new Texture();
|
||||
m_texture->Init(imgPath, Index);
|
||||
Init();
|
||||
CalcRenderInfoLogic(); // 第一次计算
|
||||
}
|
||||
|
||||
Sprite::Sprite(std::string PngPath)
|
||||
@@ -31,7 +44,6 @@ Sprite::Sprite(std::string PngPath)
|
||||
m_texture = new Texture();
|
||||
m_texture->Init(PngPath);
|
||||
Init();
|
||||
CalcRenderInfoLogic(); // 第一次计算
|
||||
}
|
||||
|
||||
Sprite::~Sprite()
|
||||
@@ -43,140 +55,19 @@ RefPtr<Texture> Sprite::GetTexture()
|
||||
return m_texture;
|
||||
}
|
||||
|
||||
void Sprite::CalcRenderInfoLogic()
|
||||
void Sprite::OnRender()
|
||||
{
|
||||
// 获取至在最终的父对象检查是否显示
|
||||
BaseNode *parentNode = this->GetParent();
|
||||
while (parentNode != nullptr)
|
||||
{
|
||||
if (parentNode->Visible == false)
|
||||
{
|
||||
_RenderGuidanceInfo.Visible = false;
|
||||
return;
|
||||
}
|
||||
parentNode = parentNode->GetParent();
|
||||
}
|
||||
_RenderGuidanceInfo.Visible = true;
|
||||
|
||||
// 计算缩放因子和翻转状态
|
||||
float scaleX = transformIter.scale.x * transform.scale.x;
|
||||
float scaleY = transformIter.scale.y * transform.scale.y;
|
||||
|
||||
// X轴和Y轴上是否翻转的标志
|
||||
bool flipX = scaleX < 0;
|
||||
bool flipY = scaleY < 0;
|
||||
|
||||
_RenderGuidanceInfo.flip = SDL_FLIP_NONE;
|
||||
// 更新翻转状态
|
||||
if (flipX)
|
||||
_RenderGuidanceInfo.flip = static_cast<SDL_RendererFlip>(SDL_FLIP_HORIZONTAL | _RenderGuidanceInfo.flip);
|
||||
if (flipY)
|
||||
_RenderGuidanceInfo.flip = static_cast<SDL_RendererFlip>(SDL_FLIP_VERTICAL | _RenderGuidanceInfo.flip);
|
||||
|
||||
// 纹理数据里带的偏移数据 有这个偏移才能保证动画播放时视觉中心点在一个点上
|
||||
auto T_Size = m_texture->getSize();
|
||||
auto T_Pos = m_texture->getPos();
|
||||
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;
|
||||
float RealPosY = transform.position.y + texturePosY;
|
||||
|
||||
// 计算在世界中的位置
|
||||
float baseX = transformIter.position.x + RealPosX;
|
||||
float baseY = transformIter.position.y + RealPosY;
|
||||
|
||||
// 获取当前帧的原始尺寸
|
||||
float frameWidth = (float)Size.width;
|
||||
float frameHeight = (float)Size.height;
|
||||
|
||||
// 原始锚点偏移(基于帧尺寸)
|
||||
float origAnchorOffsetX = frameWidth * Anchor.x;
|
||||
float origAnchorOffsetY = frameHeight * Anchor.y;
|
||||
|
||||
// 缩放的绝对值
|
||||
float absScaleX = SDL_fabsf(scaleX);
|
||||
float absScaleY = SDL_fabsf(scaleY);
|
||||
// 缩放后的尺寸
|
||||
float scaledWidth = frameWidth * absScaleX;
|
||||
float scaledHeight = frameHeight * absScaleY;
|
||||
// 缩放后的锚点偏移
|
||||
float scaledAnchorOffsetX = origAnchorOffsetX * absScaleX;
|
||||
float scaledAnchorOffsetY = origAnchorOffsetY * absScaleY;
|
||||
|
||||
// 计算缩放后的锚点偏移与原锚点偏移的差值
|
||||
float scaleOffsetX = scaledAnchorOffsetX - origAnchorOffsetX;
|
||||
float scaleOffsetY = scaledAnchorOffsetY - origAnchorOffsetY;
|
||||
|
||||
// 最终位置计算:世界位置 + 缩放锚点差值 - 缩放后的锚点偏移 + 纹理数据里带的偏移数据 (计算出绘制点的左上角)
|
||||
float Xpos = baseX - scaleOffsetX;
|
||||
float Ypos = baseY - scaleOffsetY;
|
||||
|
||||
// 更新渲染信息
|
||||
_RenderGuidanceInfo.rect = {Xpos, Ypos, scaledWidth, scaledHeight};
|
||||
_RenderGuidanceInfo.AnchorPos = {scaledAnchorOffsetX, scaledAnchorOffsetY};
|
||||
// 设置纹理透明度
|
||||
m_texture->setAlpha(this->Alpha);
|
||||
|
||||
// 屏幕内检测
|
||||
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;
|
||||
|
||||
// this->Size = {scaledWidth, scaledHeight};
|
||||
_RenderGuidanceInfo.rotation = transformIter.rotation + transform.rotation;
|
||||
|
||||
CalcRenderInfoFlag = false;
|
||||
}
|
||||
|
||||
void Sprite::PreRender()
|
||||
{
|
||||
if (CalcRenderInfoFlag && Visible)
|
||||
CalcRenderInfoLogic();
|
||||
}
|
||||
|
||||
void Sprite::Render()
|
||||
{
|
||||
if (!Visible)
|
||||
return;
|
||||
if (!m_texture)
|
||||
if (!m_texture || !IsVisible())
|
||||
return;
|
||||
|
||||
RenderManager *renderer = Game::GetInstance().GetRenderer();
|
||||
|
||||
if (_RenderGuidanceInfo.IsInScreen && _RenderGuidanceInfo.Visible)
|
||||
if (this->_BlendMode != NONE)
|
||||
{
|
||||
SDL_FPoint AnchorPos;
|
||||
AnchorPos.x = _RenderGuidanceInfo.AnchorPos.x;
|
||||
AnchorPos.y = _RenderGuidanceInfo.AnchorPos.y;
|
||||
|
||||
// 混合
|
||||
if (this->_BlendMode != NONE)
|
||||
Blend();
|
||||
|
||||
SDL_Rect srcrect = {0, 0, this->Size.width, this->Size.height};
|
||||
renderer->DrawTexture(m_texture, &srcrect, &_RenderGuidanceInfo.rect, _RenderGuidanceInfo.rotation, &AnchorPos, _RenderGuidanceInfo.flip);
|
||||
|
||||
// 还原混合
|
||||
if (this->_BlendMode != NONE)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
}
|
||||
|
||||
void Sprite::Clear()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Sprite::Blend()
|
||||
{
|
||||
switch (this->_BlendMode)
|
||||
{
|
||||
case LINEARDODGE:
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
|
||||
break;
|
||||
renderer->SetBlendMode(this->_BlendMode);
|
||||
}
|
||||
renderer->DrawTexture(m_texture);
|
||||
if (this->_BlendMode != NONE)
|
||||
{
|
||||
renderer->SetBlendMode(NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "Asset/Asset_ImagePack.h"
|
||||
#include "EngineFrame/Component/RenderBase.h"
|
||||
#include "EngineFrame/Render/Texture.h"
|
||||
#include "EngineFrame/Base/Actor.h"
|
||||
|
||||
class Game;
|
||||
/**
|
||||
* @brief Sprite类,继承自Component类,用于表示游戏中的精灵组件
|
||||
*/
|
||||
class Sprite : public RenderBase
|
||||
class Sprite : public Actor
|
||||
{
|
||||
protected:
|
||||
RefPtr<Texture> m_texture = nullptr;
|
||||
@@ -18,24 +18,18 @@ public:
|
||||
Sprite(std::string imgPath, int Index);
|
||||
Sprite(std::string PngPath);
|
||||
~Sprite();
|
||||
void Render() override;
|
||||
void PreRender() override;
|
||||
void Clear() override;
|
||||
void Init() override;
|
||||
void SetTexture(RefPtr<Texture> texture);
|
||||
|
||||
void SetTexture(RefPtr<Texture> texture);
|
||||
RefPtr<Texture> GetTexture();
|
||||
|
||||
public:
|
||||
// 渲染信息
|
||||
RenderGuidanceInfo _RenderGuidanceInfo;
|
||||
/**重载生成渲染矩阵函数 */
|
||||
void GenerateRenderMatrix() const override;
|
||||
/**重载初始化函数 */
|
||||
void Init() override;
|
||||
/**重载渲染函数 */
|
||||
void OnRender() override;
|
||||
|
||||
public:
|
||||
std::string imgPath;
|
||||
int Index;
|
||||
|
||||
public:
|
||||
// 计算渲染信息
|
||||
void CalcRenderInfoLogic();
|
||||
// 混合
|
||||
void Blend();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user