#include "dl_sprite.h" #ifndef DL_DISABLE_RENDER #include "io/dl_input.h" #include "render/dl_factory.h" #include "render/dl_graphics.h" #include "system/dl_system.h" namespace dl { void Sprite::Render() { #ifndef NDEBUG if (_bDelete) log_warn("精灵已删除,只是缓存在内存池而暂时没有崩溃!"); if (_bRender) { log_warn("此帧已调用了绘制,请勿重复调用!RenderSprite创建的精灵会自动Render!"); return; } if (g_input->KeyUp(KeyCode::PAUSE) && IsPickup()) { log_pause("pause键检测当前精灵:{}", "xx"); } #endif if (_ui && IsPickup()) { if (g_system->GetStep() != SystemStep::RENDER) { log_err0("请在Render函数调用,否则无法正确处理拾取穿透!"); } g_factory->SetOrderPickup(_order); g_factory->_add_pickup_sprite(this); } g_factory->_render_sprite(this); _bRender = true; } void Sprite::SetOrder(float order) { if (order < 0) { log_err("设置范围错误,必须是[0, 1):{}", order); _order = 0; } else if (order >= 1.0f) { log_err("设置范围错误,必须是[0, 1):{}", order); _order = 1.0f - std::numeric_limits::epsilon(); } else _order = order; } void Sprite::SetQuad(const Quad& quad) { _quad = quad; } void Sprite::SetQuad(QuadParam& param) { param._size = g_factory->GetSpriteTexSize(GetID()); _quad = createQuad(param); } void Sprite::SetQuadOrigin() { SetQuad(g_factory->GetSpriteQuad(GetID())); } void Sprite::DtQuadRotate(float rotate) { Float _cosR = std::cos(rotate); Float _sinRNag = -std::sin(rotate); for(auto& pos : _quad) { Float cos_a = _cosR * pos[0]; Float cos_b = _cosR * pos[1]; Float sin_a = _sinRNag * pos[0]; Float sin_b = _sinRNag * pos[1]; pos[0] = cos_a + sin_b; pos[1] = cos_b - sin_a; } } void Sprite::DtQuadScale(const Position& scale) { for(auto& pos : _quad) { pos *= scale; } } void Sprite::SetColor(const Color& c) { for (auto& iter : _col) iter = c; } void Sprite::SetColor(const Color& col, size_t index) { if (index >= _col.size()) { log_err("越界:{}", index); return; } _col[index] = col; } void Sprite::SetUI(bool ui, bool change_sampler /*= true*/) { _ui = ui; if (change_sampler) { SetSampler(g_factory->GetSpriteSampler(_ui)); } } void Sprite::SetUV(size_t index, const UV& uv) { if (index >= _uv.size()) { log_err("越界:{}", index); return; } _id._rect = -1; _uv[index] = uv; } UV Sprite::GetUV(size_t index) { if (index >= _uv.size()) { log_err("越界:{}", index); return {}; } return _uv[index]; } bool Sprite::IsColorOne() { return _col[0][3] == 1.0f && _col[1][3] == 1.0f && _col[2][3] == 1.0f && _col[3][3] == 1.0f; } bool Sprite::IsPickup() { if (_ui && g_factory->GetOrderPickup() < _order) { return false; } // 鼠标转换到自己坐标系 Position pos =toPosition(g_input->GetCursorPosition()); if(_coor) pos = _coor->WorldToThis(pos); bool ret = Math::IsDotInTriangle(pos, Math::GetQuadTriangle0(_quad)) || Math::IsDotInTriangle(pos, Math::GetQuadTriangle1(_quad)); return ret; } void Sprite::RenderDebug() { g_gfx->SetCoor(_coor); g_gfx->SetOrder(Math::OffsetOrder(_order, 0, 0, -1)); g_gfx->SetColor(createColor(ColorDef::GREEN, 0.2f)); g_gfx->QuadSolid2D(_quad); g_gfx->SetColor(createColor(ColorDef::RED, 1.0f)); g_gfx->Line2D(_quad.Get(0), _quad.Get(2)); g_gfx->Line2D(_quad.Get(1), _quad.Get(3)); } Sprite::~Sprite() { #ifndef NDEBUG _bDelete = true; if (_bRender) log_warn("已调用了绘制,但进行了释放,请持有精灵对象,或使用 RenderSprite创建临时精灵!"); #endif if (_bOwnCoor) delete _coor; } //-----------------------------------------SpriteSheet----------------------------------------- SpriteSheet::SpriteSheet() : _t(0), _fps(0), _coor(nullptr), _bOwnCoor{false} { } gcSprite SpriteSheet::operator[](size_t index) { if (index >= _allSprite.size()) { log_err("越界:{}", index); return g_factory->CreateSpriteDefault(); } return _allSprite[index]; } const gcSprite SpriteSheet::Get(size_t index) const { if (index >= _allSprite.size()) { log_err("越界:{}", index); return g_factory->CreateSpriteDefault(); } return _allSprite[index]; } void SpriteSheet::PushBack(gcSprite spr) { _allSprite.push_back(spr); if (spr->IsOwnCoor()) spr->GetCoor()->SetParent(_coor); else spr->SetCoor(_coor); } void SpriteSheet::SetCoor(Coor* coor, bool own /*= false*/) { _coor = coor; _bOwnCoor = own; for (gcSprite& spr : _allSprite) { if (spr->IsOwnCoor()) spr->GetCoor()->SetParent(_coor); else spr->SetCoor(_coor); } } void SpriteSheet::SetOrder(float order) { for (int i = 0; i != _allSprite.size(); ++i) _allSprite[i]->SetOrder(order); } void SpriteSheet::RenderFrame(size_t index) { if (index >= _allSprite.size()) { log_err("越界:{}", index); return; } _allSprite[index]->Render(); } void SpriteSheet::Render(Float dt) { if (_fps) { _t += dt; unsigned frm = unsigned(_t * _fps); if (frm >= _allSprite.size() * 10) { _t = 0; RenderFrame(0); } else RenderFrame(size_t(frm % _allSprite.size())); } else RenderFrame(0); } SpriteSheet::~SpriteSheet() { if(_bOwnCoor) delete _coor; } } #endif