Files
dl_old/dl/render/dl_sprite.cpp
T
2026-09-02 15:41:27 +08:00

300 lines
5.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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<float>::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