优化画布类
This commit is contained in:
@@ -3,10 +3,11 @@
|
||||
#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(size);
|
||||
m_sprite = new Sprite();
|
||||
m_sprite->SetTexture(m_texture);
|
||||
m_texture->Init(VecSize(Game::GetInstance().Screen_W, Game::GetInstance().Screen_H));
|
||||
|
||||
Actor::Init();
|
||||
|
||||
@@ -25,38 +26,90 @@ Canvas::Canvas(VecSize size)
|
||||
|
||||
void Canvas::PreRender()
|
||||
{
|
||||
if (m_dirty)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo); // 绑定FBO
|
||||
// glViewport(0, 0, m_texture->getSize().width, m_texture->getSize().height);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 全透明黑色
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
Actor::PreRender();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sprite->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)
|
||||
{
|
||||
|
||||
Actor::Render();
|
||||
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
|
||||
// glViewport(0, 0, Game::GetInstance().Screen_W, Game::GetInstance().Screen_H);
|
||||
m_dirty = false;
|
||||
}
|
||||
RenderManager *renderer = Game::GetInstance().GetRenderer();
|
||||
|
||||
renderer->SetCurrentShaderProgram("flip_y");
|
||||
m_sprite->Render();
|
||||
// 混合
|
||||
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::AddChild(RefPtr<BaseNode> child)
|
||||
void Canvas::DrawImg(std::string img, int index, Vec2 pos)
|
||||
{
|
||||
m_dirty = true;
|
||||
Actor::AddChild(child);
|
||||
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);
|
||||
}
|
||||
|
||||
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<Texture> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,20 +4,51 @@
|
||||
#include "EngineFrame/Component/Sprite.h"
|
||||
class Canvas : public Actor
|
||||
{
|
||||
struct ImgKey
|
||||
{
|
||||
std::string img;
|
||||
int index;
|
||||
|
||||
bool operator<(const ImgKey &other) const
|
||||
{
|
||||
if (img != other.img)
|
||||
{
|
||||
return img < other.img; // 字符串按字典序比较
|
||||
}
|
||||
return index < other.index; // 字符串相同则比较index
|
||||
}
|
||||
};
|
||||
struct DrawInfo
|
||||
{
|
||||
ImgKey texture;
|
||||
SDL_FRect rect = {0, 0, 0, 0};
|
||||
};
|
||||
|
||||
private:
|
||||
/**纹理 */
|
||||
RefPtr<Texture> m_texture = nullptr;
|
||||
/**精灵 */
|
||||
RefPtr<Sprite> m_sprite = 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;
|
||||
|
||||
public:
|
||||
Canvas(VecSize size);
|
||||
|
||||
void PreRender() override;
|
||||
void Render() override;
|
||||
void AddChild(RefPtr<BaseNode> child) override;
|
||||
void Blend();
|
||||
|
||||
void DrawImg(std::string img, int index, Vec2 pos);
|
||||
void DrawImg(std::string img, int index, SDL_FRect rect);
|
||||
void Clear();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user