#include "Canvas.h" #include "EngineCore/Game.h" #include "EngineFrame/Render/RenderManager.h" Canvas::Canvas(VecSize size) { m_size = size; m_renderRect = {0, 0, size.width, size.height}; m_rect = {0, 0, (float)size.width, (float)size.height}; m_texture = new Texture(); m_texture->Init(VecSize(Game::GetInstance().Screen_W, Game::GetInstance().Screen_H)); Actor::Init(); 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 Canvas::PreRender() { m_rect.x = GetWorldPos().x; m_rect.y = GetWorldPos().y; } 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"); } void Canvas::DrawImg(std::string img, int index, Vec2 pos) { 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 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); } void Canvas::DrawImg(std::string img, int index, SDL_FRect rect) { m_dirty = true; ImgKey key = {img, index}; DrawInfo info; info.rect = rect; info.texture = key; if (m_imgMap.find(key) == m_imgMap.end()) { RefPtr tex = new Texture(); tex->Init(img, index); m_imgMap[key] = tex; } m_drawQueue.push_back(info); } void Canvas::Clear() { m_drawQueue.clear(); m_dirty = true; } void Canvas::Blend() { switch (this->_BlendMode) { case LINEARDODGE: glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE); break; } }