Magic_Game/core/Transition/TransitionBase.cpp

136 lines
2.7 KiB
C++

#include "..\e2dbase.h"
#include "..\e2dtransition.h"
#include "..\e2dnode.h"
e2d::TransitionBase::TransitionBase(double duration)
: _bEnd(false)
, _fLast(0)
, _delta(0)
, _pPrevScene(nullptr)
, _pNextScene(nullptr)
, _pPrevLayer(nullptr)
, _pNextLayer(nullptr)
, _sPrevLayerParam()
, _sNextLayerParam()
{
_duration = max(duration, 0);
}
e2d::TransitionBase::~TransitionBase()
{
SafeReleaseInterface(&_pPrevLayer);
SafeReleaseInterface(&_pNextLayer);
}
bool e2d::TransitionBase::isDone()
{
return _bEnd;
}
void e2d::TransitionBase::onDestroy()
{
SafeRelease(&_pPrevScene);
SafeRelease(&_pNextScene);
}
void e2d::TransitionBase::_init(Scene * prev, Scene * next)
{
// 创建图层
HRESULT hr = Renderer::getRenderTarget()->CreateLayer(&_pNextLayer);
if (SUCCEEDED(hr))
{
hr = Renderer::getRenderTarget()->CreateLayer(&_pPrevLayer);
}
if (FAILED(hr))
{
ASSERT(false, "Create layer failed!");
}
_fLast = Time::getTotalTime();
_pPrevScene = prev;
_pNextScene = next;
if (_pPrevScene) _pPrevScene->retain();
if (_pNextScene) _pNextScene->retain();
_WindowSize = Window::getSize();
_sPrevLayerParam = _sNextLayerParam = D2D1::LayerParameters();
}
void e2d::TransitionBase::_update()
{
// 计算动画进度
if (_duration == 0)
{
_delta = 1;
}
else
{
_delta = min((Time::getTotalTime() - _fLast) / _duration, 1);
}
this->_updateCustom();
// 更新场景内容
if (_pPrevScene)
{
_pPrevScene->_update();
}
if (_pNextScene)
{
_pNextScene->_update();
}
}
void e2d::TransitionBase::_render()
{
auto pRT = Renderer::getRenderTarget();
if (_pPrevScene)
{
Point rootPos = _pPrevScene->getRoot()->getPos();
auto clipRect = D2D1::RectF(
float(max(rootPos.x, 0)),
float(max(rootPos.y, 0)),
float(min(rootPos.x + _WindowSize.width, _WindowSize.width)),
float(min(rootPos.y + _WindowSize.height, _WindowSize.height))
);
pRT->SetTransform(D2D1::Matrix3x2F::Identity());
pRT->PushAxisAlignedClip(clipRect, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
pRT->PushLayer(_sPrevLayerParam, _pPrevLayer);
// 渲染场景
_pPrevScene->_render();
pRT->PopLayer();
pRT->PopAxisAlignedClip();
}
if (_pNextScene)
{
Point rootPos = _pNextScene->getRoot()->getPos();
auto clipRect = D2D1::RectF(
float(max(rootPos.x, 0)),
float(max(rootPos.y, 0)),
float(min(rootPos.x + _WindowSize.width, _WindowSize.width)),
float(min(rootPos.y + _WindowSize.height, _WindowSize.height))
);
pRT->SetTransform(D2D1::Matrix3x2F::Identity());
pRT->PushAxisAlignedClip(clipRect, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
pRT->PushLayer(_sNextLayerParam, _pNextLayer);
// 渲染场景
_pNextScene->_render();
pRT->PopLayer();
pRT->PopAxisAlignedClip();
}
}
void e2d::TransitionBase::_stop()
{
_bEnd = true;
_reset();
}