300 lines
5.1 KiB
C++
300 lines
5.1 KiB
C++
#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 |