修改OpenGl渲染底层之前

This commit is contained in:
2025-10-20 20:50:12 +08:00
parent 1b011b9b68
commit 2b888aae5b
61 changed files with 1609 additions and 680 deletions

View File

@@ -0,0 +1,107 @@
#include "AnimationManager.h"
#include "EngineCore/Game.h"
AnimationManager::AnimationManager()
{
SDL_Renderer *renderer = Game::GetInstance().GetRenderer();
m_Texture = SDL_CreateTexture(
renderer,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_TARGET,
Game::GetInstance().Screen_W,
Game::GetInstance().Screen_H);
}
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()
{
SDL_Renderer *renderer = Game::GetInstance().GetRenderer();
// 设定渲染目标为纹理
SDL_SetRenderTarget(renderer, m_Texture);
SDL_RenderClear(renderer);
// 渲染所有子对象
Actor::Render();
// 恢复渲染目标为默认窗口
SDL_SetRenderTarget(renderer, nullptr);
SDL_Rect srcRect = {
static_cast<int>(m_RenderRect.x), // 子对象包围盒左上角X纹理中的位置
static_cast<int>(m_RenderRect.y), // 子对象包围盒左上角Y纹理中的位置
static_cast<int>(m_RenderRect.w), // 包围盒宽度(有效区域宽度)
static_cast<int>(m_RenderRect.h) // 包围盒高度(有效区域高度)
};
// SDL_FRect renderToWindow = {
// m_RenderRect.x, // 窗口上的X位置可自定义
// m_RenderRect.y, // 窗口上的Y位置可自定义
// m_RenderRect.w, // 渲染到窗口的宽度(与源区域等大)
// m_RenderRect.h // 渲染到窗口的高度(与源区域等大)
// };
SDL_FRect renderToWindow = {
0, 0, 1080, 720};
// SDL_Log("m_Texture rect: %f %f %f %f", renderToWindow.x, renderToWindow.y, renderToWindow.w, renderToWindow.h);
// SDL_RenderCopyF(renderer, m_Texture, &srcRect, &renderToWindow);
SDL_RenderCopyF(renderer, m_Texture, NULL, &renderToWindow);
}
void AnimationManager::AddAnimation(RefPtr<Animation> ani)
{
this->AddChild(ani);
}
void AnimationManager::Clear()
{
this->RemoveAllChild();
}