This commit is contained in:
2026-02-08 16:20:50 +08:00
parent 0ae47e5d6a
commit 8b88904ef7
72 changed files with 5963 additions and 2038 deletions

View File

@@ -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");
// }