update Layer && Transform

This commit is contained in:
Nomango 2019-08-20 19:32:36 +08:00
parent 3c47aaf007
commit ff8a05c3ac
53 changed files with 788 additions and 734 deletions

View File

@ -37,7 +37,7 @@
<ClInclude Include="..\src\kiwano\2d\Sprite.h" />
<ClInclude Include="..\src\kiwano\2d\Text.h" />
<ClInclude Include="..\src\kiwano\2d\TextStyle.hpp" />
<ClInclude Include="..\src\kiwano\2d\Transform.hpp" />
<ClInclude Include="..\src\kiwano\2d\Transform.h" />
<ClInclude Include="..\src\kiwano\2d\Transition.h" />
<ClInclude Include="..\src\kiwano\base\AsyncTask.h" />
<ClInclude Include="..\src\kiwano\base\Component.h" />
@ -111,6 +111,7 @@
<ClCompile Include="..\src\kiwano\2d\Stage.cpp" />
<ClCompile Include="..\src\kiwano\2d\Sprite.cpp" />
<ClCompile Include="..\src\kiwano\2d\Text.cpp" />
<ClCompile Include="..\src\kiwano\2d\Transform.cpp" />
<ClCompile Include="..\src\kiwano\2d\Transition.cpp" />
<ClCompile Include="..\src\kiwano\base\AsyncTask.cpp" />
<ClCompile Include="..\src\kiwano\base\EventDispatcher.cpp" />

View File

@ -66,9 +66,6 @@
<ClInclude Include="..\src\kiwano\2d\TextStyle.hpp">
<Filter>2d</Filter>
</ClInclude>
<ClInclude Include="..\src\kiwano\2d\Transform.hpp">
<Filter>2d</Filter>
</ClInclude>
<ClInclude Include="..\src\kiwano\2d\Transition.h">
<Filter>2d</Filter>
</ClInclude>
@ -306,6 +303,9 @@
<ClInclude Include="..\src\kiwano\core\types.h">
<Filter>core</Filter>
</ClInclude>
<ClInclude Include="..\src\kiwano\2d\Transform.h">
<Filter>2d</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\src\kiwano\ui\Button.cpp">
@ -479,5 +479,8 @@
<ClCompile Include="..\src\kiwano\renderer\FontCollection.cpp">
<Filter>renderer</Filter>
</ClCompile>
<ClCompile Include="..\src\kiwano\2d\Transform.cpp">
<Filter>2d</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -33,9 +33,9 @@ namespace kiwano
{
}
void ImGuiLayer::OnRender(Renderer* renderer)
void ImGuiLayer::OnRender(RenderTarget* rt)
{
PrepareRender(renderer);
PrepareRender(rt);
for (const auto& pipeline : pipelines_)
{
pipeline.second();

View File

@ -52,7 +52,7 @@ namespace kiwano
void RemoveAllItems();
public:
void OnRender(Renderer* renderer) override;
void OnRender(RenderTarget* rt) override;
protected:
Map<String, ImGuiPipeline> pipelines_;

View File

@ -71,7 +71,7 @@ namespace kiwano
OnUpdate(dt);
}
if (!children_.item_empty())
if (!children_.empty())
{
ActorPtr next;
for (auto child = children_.first_item(); child; child = next)
@ -82,16 +82,16 @@ namespace kiwano
}
}
void Actor::Render(Renderer* renderer)
void Actor::Render(RenderTarget* rt)
{
if (!visible_)
return;
UpdateTransform();
if (children_.item_empty())
if (children_.empty())
{
OnRender(renderer);
OnRender(rt);
}
else
{
@ -102,41 +102,40 @@ namespace kiwano
if (child->GetZOrder() >= 0)
break;
child->Render(renderer);
child->Render(rt);
child = child->next_item().get();
}
OnRender(renderer);
OnRender(rt);
while (child)
{
child->Render(renderer);
child->Render(rt);
child = child->next_item().get();
}
}
}
void Actor::PrepareRender(Renderer* renderer)
void Actor::PrepareRender(RenderTarget* rt)
{
renderer->SetTransform(transform_matrix_);
renderer->SetOpacity(displayed_opacity_);
rt->SetTransform(transform_matrix_);
rt->SetOpacity(displayed_opacity_);
}
void Actor::RenderBorder()
void Actor::RenderBorder(RenderTarget* rt)
{
if (show_border_)
if (show_border_ && !size_.IsOrigin())
{
Rect bounds = GetBounds();
auto renderer = Renderer::GetInstance();
renderer->SetTransform(transform_matrix_);
renderer->FillRectangle(bounds, Color(Color::Red, .4f));
renderer->DrawRectangle(bounds, Color(Color::Red, .8f), 2.f);
rt->SetTransform(transform_matrix_);
rt->FillRectangle(bounds, Color(Color::Red, .4f));
rt->DrawRectangle(bounds, Color(Color::Red, .8f), 2.f);
}
for (auto child = children_.first_item(); child; child = child->next_item())
{
child->RenderBorder();
child->RenderBorder(rt);
}
}
@ -233,12 +232,7 @@ namespace kiwano
else
{
// matrix multiplication is optimized by expression template
transform_matrix_ = Matrix3x2::SRT(transform_.position, transform_.scale, transform_.rotation);
if (!transform_.skew.IsOrigin())
{
transform_matrix_ = Matrix3x2::Skewing(transform_.skew) * transform_matrix_;
}
transform_matrix_ = transform_.ToMatrix();
}
transform_matrix_.Translate(Point{ -size_.x * anchor_.x, -size_.y * anchor_.y });
@ -270,14 +264,14 @@ namespace kiwano
}
}
void Actor::SetStage(Stage* scene)
void Actor::SetStage(Stage* stage)
{
if (scene && stage_ != scene)
if (stage && stage_ != stage)
{
stage_ = scene;
stage_ = stage;
for (Actor* child = children_.first_item().get(); child; child = child->next_item().get())
{
child->stage_ = scene;
child->stage_ = stage;
}
}
}
@ -288,7 +282,7 @@ namespace kiwano
{
ActorPtr me = this;
parent_->children_.remove_item(me);
parent_->children_.remove(me);
Actor* sibling = parent_->children_.last_item().get();
@ -309,7 +303,7 @@ namespace kiwano
}
else
{
parent_->children_.push_front_item(me);
parent_->children_.push_front(me);
}
}
}
@ -341,53 +335,31 @@ namespace kiwano
UpdateOpacity();
}
void Actor::SetAnchorX(Float32 anchor_x)
void Actor::SetAnchor(Vec2 const& anchor)
{
this->SetAnchor(anchor_x, anchor_.y);
}
void Actor::SetAnchorY(Float32 anchor_y)
{
this->SetAnchor(anchor_.x, anchor_y);
}
void Actor::SetAnchor(Float32 anchor_x, Float32 anchor_y)
{
if (anchor_.x == anchor_x && anchor_.y == anchor_y)
if (anchor_ == anchor)
return;
anchor_.x = anchor_x;
anchor_.y = anchor_y;
anchor_ = anchor;
dirty_transform_ = true;
}
void Actor::SetAnchor(Point const& anchor)
{
this->SetAnchor(anchor.x, anchor.y);
}
void Actor::SetWidth(Float32 width)
{
this->SetSize(width, size_.y);
SetSize(Size{ width, size_.y });
}
void Actor::SetHeight(Float32 height)
{
this->SetSize(size_.x, height);
SetSize(Size{ size_.x, height });
}
void Actor::SetSize(const Size& size)
void Actor::SetSize(Size const& size)
{
this->SetSize(size.x, size.y);
}
void Actor::SetSize(Float32 width, Float32 height)
{
if (size_.x == width && size_.y == height)
if (size_ == size)
return;
size_.x = width;
size_.y = height;
size_ = size;
dirty_transform_ = true;
}
@ -412,98 +384,50 @@ namespace kiwano
}
}
void Actor::SetPosition(const Point & pos)
{
if (transform_.position == pos)
return;
transform_.position = pos;
dirty_transform_ = true;
}
void Actor::SetPositionX(Float32 x)
{
this->SetPosition(x, transform_.position.y);
SetPosition(Point{ x, transform_.position.y });
}
void Actor::SetPositionY(Float32 y)
{
this->SetPosition(transform_.position.x, y);
SetPosition(Point{ transform_.position.x, y });
}
void Actor::SetPosition(const Point & p)
void Actor::Move(Vec2 const& v)
{
this->SetPosition(p.x, p.y);
this->SetPosition(Point{ transform_.position.x + v.x, transform_.position.y + v.y });
}
void Actor::SetPosition(Float32 x, Float32 y)
void Actor::SetScale(Vec2 const& scale)
{
if (transform_.position.x == x && transform_.position.y == y)
if (transform_.scale == scale)
return;
transform_.position.x = x;
transform_.position.y = y;
dirty_transform_ = true;
}
void Actor::Move(Float32 x, Float32 y)
{
this->SetPosition(transform_.position.x + x, transform_.position.y + y);
}
void Actor::Move(const Point & v)
{
this->Move(v.x, v.y);
}
void Actor::SetScaleX(Float32 scale_x)
{
this->SetScale(scale_x, transform_.scale.y);
}
void Actor::SetScaleY(Float32 scale_y)
{
this->SetScale(transform_.scale.x, scale_y);
}
void Actor::SetScale(Float32 scale)
{
this->SetScale(scale, scale);
}
void Actor::SetScale(Float32 scale_x, Float32 scale_y)
{
if (transform_.scale.x == scale_x && transform_.scale.y == scale_y)
return;
transform_.scale.x = scale_x;
transform_.scale.y = scale_y;
transform_.scale = scale;
dirty_transform_ = true;
is_fast_transform_ = false;
}
void Actor::SetScale(Point const& scale)
void Actor::SetSkew(Vec2 const& skew)
{
this->SetScale(scale.x, scale.y);
}
void Actor::SetSkewX(Float32 skew_x)
{
this->SetSkew(skew_x, transform_.skew.y);
}
void Actor::SetSkewY(Float32 skew_y)
{
this->SetSkew(transform_.skew.x, skew_y);
}
void Actor::SetSkew(Float32 skew_x, Float32 skew_y)
{
if (transform_.skew.x == skew_x && transform_.skew.y == skew_y)
if (transform_.skew == skew)
return;
transform_.skew.x = skew_x;
transform_.skew.y = skew_y;
transform_.skew = skew;
dirty_transform_ = true;
is_fast_transform_ = false;
}
void Actor::SetSkew(Point const& skew)
{
this->SetSkew(skew.x, skew.y);
}
void Actor::SetRotation(Float32 angle)
{
if (transform_.rotation == angle)
@ -531,7 +455,7 @@ namespace kiwano
#endif // KGE_DEBUG
children_.push_back_item(child);
children_.push_back(child);
child->parent_ = this;
child->SetStage(this->stage_);
child->dirty_transform_ = true;
@ -550,7 +474,7 @@ namespace kiwano
Rect Actor::GetBounds() const
{
return Rect(Point{}, size_);
return Rect{ Point{}, size_ };
}
Rect Actor::GetBoundingBox() const
@ -609,20 +533,20 @@ namespace kiwano
{
KGE_ASSERT(child && "Actor::RemoveChild failed, NULL pointer exception");
if (children_.item_empty())
if (children_.empty())
return;
if (child)
{
child->parent_ = nullptr;
if (child->stage_) child->SetStage(nullptr);
children_.remove_item(ActorPtr(child));
children_.remove(ActorPtr(child));
}
}
void Actor::RemoveChildren(String const& child_name)
{
if (children_.item_empty())
if (children_.empty())
{
return;
}
@ -643,7 +567,7 @@ namespace kiwano
void Actor::RemoveAllChildren()
{
children_.clear_items();
children_.clear();
}
void Actor::SetResponsible(bool enable)

View File

@ -20,7 +20,7 @@
#pragma once
#include "include-forwards.h"
#include "Transform.hpp"
#include "Transform.h"
#include "action/ActionManager.h"
#include "../base/TimerManager.h"
#include "../base/EventDispatcher.h"
@ -28,7 +28,7 @@
namespace kiwano
{
class Director;
class Renderer;
class RenderTarget;
// 角色
class KGE_API Actor
@ -52,7 +52,7 @@ namespace kiwano
virtual void OnUpdate(Duration dt) { KGE_UNUSED(dt); }
// 渲染角色
virtual void OnRender(Renderer* renderer) { KGE_UNUSED(renderer); }
virtual void OnRender(RenderTarget* rt) { KGE_UNUSED(rt); }
// 获取显示状态
bool IsVisible() const { return visible_; }
@ -163,6 +163,20 @@ namespace kiwano
String const& name
);
// 设置坐标
virtual void SetPosition(
Point const& point
);
// 设置坐标
inline void SetPosition(
Float32 x,
Float32 y
)
{
SetPosition(Point{ x, y });
}
// 设置横坐标
void SetPositionX(
Float32 x
@ -173,144 +187,101 @@ namespace kiwano
Float32 y
);
// 设置坐标
void SetPosition(
const Point & point
);
// 设置坐标
void SetPosition(
Float32 x,
Float32 y
);
// 移动
// 移动坐标
void Move(
Float32 x,
Float32 y
Vec2 const& v
);
// 移动
void Move(
const Point & vector
);
// 移动坐标
inline void Move(
Float32 vx,
Float32 vy
)
{
Move(Vec2{ vx, vy });
}
// 设置横向缩放比例
// 默认为 1.0
void SetScaleX(
Float32 scale_x
);
// 设置纵向缩放比例
// 默认为 1.0
void SetScaleY(
Float32 scale_y
// 设置缩放比例
// 默认为 (1.0, 1.0)
virtual void SetScale(
Vec2 const& scale
);
// 设置缩放比例
// 默认为 (1.0, 1.0)
void SetScale(
Float32 scale_x,
Float32 scale_y
);
inline void SetScale(
Float32 scalex,
Float32 scaley
)
{
SetScale(Vec2{ scalex, scaley });
}
// 设置缩放比例
// 默认为 (1.0, 1.0)
void SetScale(
Point const& scale
);
// 设置缩放比例
// 默认为 1.0
void SetScale(
Float32 scale
);
// 设置横向错切角度
// 默认为 0
void SetSkewX(
Float32 skew_x
);
// 设置纵向错切角度
// 默认为 0
void SetSkewY(
Float32 skew_y
// 设置错切角度
// 默认为 (0, 0)
virtual void SetSkew(
Vec2 const& skew
);
// 设置错切角度
// 默认为 (0, 0)
void SetSkew(
Float32 skew_x,
Float32 skew_y
);
// 设置错切角度
// 默认为 (0, 0)
void SetSkew(
Point const& skew
);
inline void SetSkew(
Float32 skewx,
Float32 skewy
)
{
SetSkew(Vec2{ skewx, skewy });
}
// 设置旋转角度
// 默认为 0
void SetRotation(
virtual void SetRotation(
Float32 rotation
);
// 设置锚点的横向位置
// 默认为 0, 范围 [0, 1]
void SetAnchorX(
Float32 anchor_x
);
// 设置锚点的纵向位置
// 默认为 0, 范围 [0, 1]
void SetAnchorY(
Float32 anchor_y
// 设置锚点位置
// 默认为 (0, 0), 范围 [0, 1]
virtual void SetAnchor(
Vec2 const& anchor
);
// 设置锚点位置
// 默认为 (0, 0), 范围 [0, 1]
void SetAnchor(
Float32 anchor_x,
Float32 anchor_y
);
// 设置锚点位置
// 默认为 (0, 0), 范围 [0, 1]
void SetAnchor(
Point const& anchor
);
inline void SetAnchor(
Float32 anchorx,
Float32 anchory
)
{
SetAnchor(Vec2{ anchorx, anchory });
}
// 修改宽度
void SetWidth(
virtual void SetWidth(
Float32 width
);
// 修改高度
void SetHeight(
virtual void SetHeight(
Float32 height
);
// 修改大小
void SetSize(
virtual void SetSize(
Size const& size
);
// 修改大小
inline void SetSize(
Float32 width,
Float32 height
);
// 修改大小
void SetSize(
const Size & size
);
// 设置二维仿射变换
void SetTransform(
Transform const& transform
);
)
{
SetSize(Size{ width, height });
}
// 设置透明度
// 默认为 1.0, 范围 [0, 1]
void SetOpacity(
virtual void SetOpacity(
Float32 opacity
);
@ -319,6 +290,11 @@ namespace kiwano
bool enabled
);
// 设置二维仿射变换
void SetTransform(
Transform const& transform
);
// 设置 Z 轴顺序
// 默认为 0
void SetZOrder(
@ -331,11 +307,6 @@ namespace kiwano
bool enable
);
// 判断点是否在角色内
bool ContainsPoint(
const Point& point
) const;
// 添加子角色
void AddChild(
ActorPtr child
@ -380,8 +351,10 @@ namespace kiwano
// 从父角色移除
void RemoveFromParent();
// 事件分发
void Dispatch(Event& evt) override;
// 判断点是否在角色内
bool ContainsPoint(
const Point& point
) const;
// 暂停角色更新
inline void PauseUpdating() { update_pausing_ = true; }
@ -401,6 +374,9 @@ namespace kiwano
// 渲染角色边界
inline void ShowBorder(bool show) { show_border_ = show; }
// 事件分发
void Dispatch(Event& evt) override;
// 设置默认锚点
static void SetDefaultAnchor(
Float32 anchor_x,
@ -410,11 +386,11 @@ namespace kiwano
protected:
virtual void Update(Duration dt);
virtual void Render(Renderer* renderer);
virtual void Render(RenderTarget* rt);
void PrepareRender(Renderer* renderer);
virtual void PrepareRender(RenderTarget* rt);
void RenderBorder();
virtual void RenderBorder(RenderTarget* rt);
void UpdateTransform() const;
@ -422,7 +398,7 @@ namespace kiwano
void Reorder();
void SetStage(Stage* scene);
void SetStage(Stage* stage);
protected:
bool visible_;

View File

@ -34,17 +34,6 @@ namespace kiwano
Renderer::GetInstance()->CreateImageRenderTarget(rt_);
}
Canvas::Canvas(Float32 width, Float32 height)
: Canvas()
{
this->SetSize(width, height);
}
Canvas::Canvas(Size const & size)
: Canvas(size.x, size.y)
{
}
Canvas::~Canvas()
{
}
@ -60,16 +49,16 @@ namespace kiwano
cache_expired_ = true;
}
void Canvas::OnRender(Renderer* renderer)
void Canvas::OnRender(RenderTarget* rt)
{
UpdateCache();
if (image_cached_.IsValid())
{
PrepareRender(renderer);
PrepareRender(rt);
Rect bitmap_rect(0.f, 0.f, image_cached_.GetWidth(), image_cached_.GetHeight());
renderer->DrawImage(image_cached_, bitmap_rect, bitmap_rect);
rt->DrawImage(image_cached_, bitmap_rect, bitmap_rect);
}
}
@ -130,13 +119,7 @@ namespace kiwano
void Canvas::SetBrushTransform(Transform const& transform)
{
Matrix3x2 matrix = Matrix3x2::SRT(transform.position, transform.scale, transform.rotation);
if (!transform.skew.IsOrigin())
{
matrix = Matrix3x2::Skewing(transform.skew) * matrix;
}
rt_.SetTransform(matrix);
rt_.SetTransform(transform.ToMatrix());
}
void Canvas::SetBrushTransform(Matrix3x2 const & transform)
@ -144,6 +127,26 @@ namespace kiwano
rt_.SetTransform(transform);
}
void Canvas::PushLayerArea(LayerArea& area)
{
rt_.PushLayer(area);
}
void Canvas::PopLayerArea()
{
rt_.PopLayer();
}
void Canvas::PushClipRect(Rect const& clip_rect)
{
rt_.PushClipRect(clip_rect);
}
void Canvas::PopClipRect()
{
rt_.PopClipRect();
}
void Canvas::DrawLine(Point const& begin, Point const& end)
{
rt_.DrawLine(
@ -333,7 +336,7 @@ namespace kiwano
{
if (cache_expired_)
{
rt_.GetOutput(image_cached_);
image_cached_ = rt_.GetOutput();
cache_expired_ = false;
}
}

View File

@ -35,15 +35,6 @@ namespace kiwano
public:
Canvas();
Canvas(
Size const& size
);
Canvas(
Float32 width,
Float32 height
);
virtual ~Canvas();
// 开始绘图
@ -202,6 +193,32 @@ namespace kiwano
Float32 opacity
);
// 画笔二维变换
void SetBrushTransform(
Transform const& transform
);
// 画笔二维变换
void SetBrushTransform(
Matrix3x2 const& transform
);
// 设置图层
void PushLayerArea(
LayerArea& area
);
// 弹出图层
void PopLayerArea();
// 设置裁剪区域
void PushClipRect(
Rect const& clip_rect
);
// 弹出裁剪区域
void PopClipRect();
// 获取填充颜色
Color GetFillColor() const;
@ -214,20 +231,10 @@ namespace kiwano
// 获取画笔透明度
Float32 GetBrushOpacity() const;
// »­±Ê¶þά±ä»»
void SetBrushTransform(
Transform const& transform
);
// »­±Ê¶þά±ä»»
void SetBrushTransform(
Matrix3x2 const& transform
);
// 导出为图片
Image ExportToImage() const;
void OnRender(Renderer* renderer) override;
void OnRender(RenderTarget* rt) override;
protected:
void UpdateCache() const;

View File

@ -48,12 +48,12 @@ namespace kiwano
: background_color_(0.0f, 0.0f, 0.0f, 0.7f)
{
SetName(L"kiwano-debug-actor");
SetPosition(10, 10);
SetPosition(Point{ 10, 10 });
SetResponsible(true);
SetCascadeOpacityEnabled(true);
debug_text_ = new Text;
debug_text_->SetPosition(10, 10);
debug_text_->SetPosition(Point{ 10, 10 });
this->AddChild(debug_text_);
Font font;
@ -74,11 +74,11 @@ namespace kiwano
{
}
void DebugActor::OnRender(Renderer* renderer)
void DebugActor::OnRender(RenderTarget* rt)
{
PrepareRender(renderer);
PrepareRender(rt);
renderer->FillRoundedRectangle(GetBounds(), Vec2{ 5.f, 5.f }, background_color_);
rt->FillRoundedRectangle(GetBounds(), Vec2{ 5.f, 5.f }, background_color_);
}
void DebugActor::OnUpdate(Duration dt)

View File

@ -31,7 +31,7 @@ namespace kiwano
virtual ~DebugActor();
void OnRender(Renderer* renderer) override;
void OnRender(RenderTarget* rt) override;
void OnUpdate(Duration dt) override;

View File

@ -69,10 +69,10 @@ namespace kiwano
if (image_.IsValid())
{
auto bitmap_size = image_.GetSize();
crop_rect_.origin.x = std::min(std::max(crop_rect.origin.x, 0.f), bitmap_size.x);
crop_rect_.origin.y = std::min(std::max(crop_rect.origin.y, 0.f), bitmap_size.y);
crop_rect_.size.x = std::min(std::max(crop_rect.size.x, 0.f), bitmap_size.x - crop_rect.origin.x);
crop_rect_.size.y = std::min(std::max(crop_rect.size.y, 0.f), bitmap_size.y - crop_rect.origin.y);
crop_rect_.left_top.x = std::min(std::max(crop_rect.left_top.x, 0.f), bitmap_size.x);
crop_rect_.left_top.y = std::min(std::max(crop_rect.left_top.y, 0.f), bitmap_size.y);
crop_rect_.right_bottom.x = std::min(std::max(crop_rect.right_bottom.x, 0.f), bitmap_size.x);
crop_rect_.right_bottom.y = std::min(std::max(crop_rect.right_bottom.y, 0.f), bitmap_size.y);
}
}
@ -81,9 +81,9 @@ namespace kiwano
image_ = image;
if (image_.IsValid())
{
crop_rect_.origin.x = crop_rect_.origin.y = 0;
crop_rect_.size.x = image_.GetWidth();
crop_rect_.size.y = image_.GetHeight();
crop_rect_.left_top.x = crop_rect_.left_top.y = 0;
crop_rect_.right_bottom.x = image_.GetWidth();
crop_rect_.right_bottom.y = image_.GetHeight();
}
}
}

View File

@ -61,16 +61,16 @@ namespace kiwano
);
// 获取宽度
Float32 GetWidth() const { return crop_rect_.size.x; }
Float32 GetWidth() const { return crop_rect_.GetWidth(); }
// 获取高度
Float32 GetHeight() const { return crop_rect_.size.y; }
Float32 GetHeight() const { return crop_rect_.GetHeight(); }
// 获取大小
Size GetSize() const { return crop_rect_.size; }
Size GetSize() const { return crop_rect_.GetSize(); }
// 获取裁剪位置
Point GetCropPoint() const { return crop_rect_.origin; }
Point GetCropPoint() const { return crop_rect_.GetLeftTop(); }
// 获取裁剪矩形
inline Rect const& GetCropRect() const { return crop_rect_; }

View File

@ -72,10 +72,7 @@ namespace kiwano
loop_count_ = 0;
disposal_type_ = DisposalType::None;
SetSize(
static_cast<Float32>(image_.GetWidthInPixels()),
static_cast<Float32>(image_.GetHeightInPixels())
);
SetSize(Size{ static_cast<Float32>(image_.GetWidthInPixels()), static_cast<Float32>(image_.GetHeightInPixels()) });
if (!frame_rt_.IsValid())
{
@ -91,13 +88,13 @@ namespace kiwano
return false;
}
void GifSprite::OnRender(Renderer* renderer)
void GifSprite::OnRender(RenderTarget* rt)
{
if (frame_.IsValid() && renderer->CheckVisibility(size_, transform_matrix_))
if (frame_.IsValid() && rt->CheckVisibility(size_, transform_matrix_))
{
PrepareRender(renderer);
PrepareRender(rt);
renderer->DrawImage(frame_);
rt->DrawImage(frame_);
}
}
@ -195,8 +192,7 @@ namespace kiwano
if (SUCCEEDED(hr))
{
Image frame_to_render;
frame_rt_.GetOutput(frame_to_render);
Image frame_to_render = frame_rt_.GetOutput();
hr = frame_to_render.IsValid() ? S_OK : E_FAIL;
@ -222,8 +218,7 @@ namespace kiwano
void GifSprite::SaveComposedFrame()
{
Image frame_to_be_saved;
frame_rt_.GetOutput(frame_to_be_saved);
Image frame_to_be_saved = frame_rt_.GetOutput();
HRESULT hr = frame_to_be_saved.IsValid() ? S_OK : E_FAIL;
@ -258,8 +253,7 @@ namespace kiwano
if (SUCCEEDED(hr))
{
Image frame_to_copy_to;
frame_rt_.GetOutput(frame_to_copy_to);
Image frame_to_copy_to = frame_rt_.GetOutput();
hr = frame_to_copy_to.IsValid() ? S_OK : E_FAIL;

View File

@ -77,7 +77,7 @@ namespace kiwano
inline DoneCallback GetDoneCallback() const { return done_cb_; }
void OnRender(Renderer* renderer) override;
void OnRender(RenderTarget* rt) override;
protected:
void Update(Duration dt) override;

View File

@ -27,8 +27,6 @@ namespace kiwano
Layer::Layer()
: swallow_(false)
{
SetSize(Renderer::GetInstance()->GetOutputSize());
auto handler = Closure(this, &Layer::HandleMessages);
AddListener(Event::MouseBtnDown, handler);
@ -45,6 +43,27 @@ namespace kiwano
{
}
void Layer::SetClipRect(Rect const& clip_rect)
{
area_.SetAreaRect(clip_rect);
}
void Layer::SetOpacity(Float32 opacity)
{
// Actor::SetOpacity(opacity);
area_.SetOpacity(opacity);
}
void Layer::SetMaskGeometry(Geometry const& mask)
{
area_.SetMaskGeometry(mask);
}
void Layer::SetMaskTransform(Matrix3x2 const& transform)
{
area_.SetMaskTransform(transform);
}
void Layer::Dispatch(Event& evt)
{
if (!IsVisible())
@ -63,6 +82,18 @@ namespace kiwano
EventDispatcher::Dispatch(evt);
}
void Layer::Render(RenderTarget* rt)
{
if (!children_.empty())
{
PrepareRender(rt);
rt->PushLayer(area_);
Actor::Render(rt);
rt->PopLayer();
}
}
void Layer::HandleMessages(Event const& evt)
{
switch (evt.type)

View File

@ -20,6 +20,8 @@
#pragma once
#include "Actor.h"
#include "..\renderer\LayerArea.h"
#include "..\renderer\RenderTarget.h"
namespace kiwano
{
@ -31,25 +33,49 @@ namespace kiwano
virtual ~Layer();
// 重载下列函数以获取图层事件
virtual void OnMouseButtonDown(Int32 btn, Point const& p) {}
virtual void OnMouseButtonUp(Int32 btn, Point const& p) {}
virtual void OnMouseMoved(Point const& p) {}
virtual void OnMouseWheel(Float32 wheel) {}
virtual void OnKeyDown(Int32 key) {}
virtual void OnKeyUp(Int32 key) {}
virtual void OnChar(char c) {}
// 是否开启消息吞没
inline bool IsSwallowEventsEnabled() const { return swallow_; }
// ÍÌûÏûÏ¢
inline void SetSwallowEvents(bool enabled) { swallow_ = enabled; }
// 设置裁剪区域
void SetClipRect(Rect const& clip_rect);
// 设置图层透明度
void SetOpacity(Float32 opacity) override;
// 设置几何蒙层
void SetMaskGeometry(Geometry const& mask);
// 设置几何蒙层的二维变换
void SetMaskTransform(Matrix3x2 const& transform);
// 设置图层区域
inline void SetArea(LayerArea const& area) { area_ = area; }
// 获取图层区域
inline LayerArea const& GetArea() const { return area_; }
public:
void Dispatch(Event& evt) override;
protected:
void Render(RenderTarget* rt) override;
void HandleMessages(Event const& evt);
protected:
bool swallow_;
LayerArea area_;
};
}

View File

@ -78,18 +78,18 @@ namespace kiwano
stroke_style_ = stroke_style;
}
void ShapeActor::OnRender(Renderer* renderer)
void ShapeActor::OnRender(RenderTarget* rt)
{
if (geo_)
if (geo_ && rt->CheckVisibility(size_, transform_matrix_))
{
PrepareRender(renderer);
PrepareRender(rt);
renderer->FillGeometry(
rt->FillGeometry(
geo_,
fill_color_
);
renderer->DrawGeometry(
rt->DrawGeometry(
geo_,
stroke_color_,
stroke_width_,
@ -106,22 +106,23 @@ namespace kiwano
{
}
LineActor::LineActor(Point const& end)
LineActor::LineActor(Point const& point)
{
SetEndPoint(end);
SetPoint(point);
}
LineActor::~LineActor()
{
}
void LineActor::SetEndPoint(Point const& end)
void LineActor::SetPoint(Point const& point)
{
geo_ = Geometry::CreateLine(Point{}, end);
geo_ = Geometry::CreateLine(Point{}, point);
if (geo_)
{
SetSize(end);
point_ = point;
SetSize(point_);
}
}
@ -149,6 +150,7 @@ namespace kiwano
if (geo_)
{
rect_size_ = size;
SetSize(size);
}
}
@ -187,6 +189,7 @@ namespace kiwano
if (geo_)
{
rect_size_ = size;
SetSize(size);
}
}
@ -216,7 +219,7 @@ namespace kiwano
if (geo_)
{
SetSize(radius * 2, radius * 2);
SetSize(Size{ radius * 2, radius * 2 });
}
}
@ -270,6 +273,12 @@ namespace kiwano
{
sink_.EndPath(closed);
geo_ = sink_.GetGeometry();
if (geo_)
{
Rect bounds = geo_.GetBoundingBox();
SetSize(bounds.GetSize());
}
}
void PathActor::AddLine(Point const& point)

View File

@ -81,7 +81,7 @@ namespace kiwano
// »ñÈ¡ÐÎ×´
inline Geometry GetGeometry() const { return geo_; }
void OnRender(Renderer* renderer) override;
void OnRender(RenderTarget* rt) override;
protected:
Color fill_color_;
@ -92,7 +92,7 @@ namespace kiwano
};
// Ö±Ïß
// Ö±Ïß½ÇÉ«
class KGE_API LineActor
: public ShapeActor
{
@ -100,19 +100,19 @@ namespace kiwano
LineActor();
LineActor(
Point const& end_pos
Point const& point
);
virtual ~LineActor();
Point const& GetEndPoint() const { return end_; }
Point const& GetPoint() const { return point_; }
void SetEndPoint(
Point const& end
void SetPoint(
Point const& point
);
protected:
Point end_;
Point point_;
};
@ -131,10 +131,10 @@ namespace kiwano
void SetRectSize(Size const& size);
inline Size const& GetRectSize() const { return size_; }
inline Size const& GetRectSize() const { return rect_size_; }
protected:
Size size_;
Size rect_size_;
};
@ -170,7 +170,7 @@ namespace kiwano
inline Size GetRectSize() const { return size_; }
protected:
Size size_;
Size rect_size_;
Vec2 radius_;
};

View File

@ -86,7 +86,7 @@ namespace kiwano
if (frame_)
{
frame_->SetCropRect(crop_rect);
SetSize(frame_->GetWidth(), frame_->GetHeight());
SetSize(Size{ frame_->GetWidth(), frame_->GetHeight() });
}
}
@ -97,18 +97,18 @@ namespace kiwano
frame_ = frame;
if (frame_)
{
SetSize(frame_->GetWidth(), frame_->GetHeight());
SetSize(Size{ frame_->GetWidth(), frame_->GetHeight() });
}
}
}
void Sprite::OnRender(Renderer* renderer)
void Sprite::OnRender(RenderTarget* rt)
{
if (frame_ && renderer->CheckVisibility(size_, transform_matrix_))
if (frame_ && rt->CheckVisibility(size_, transform_matrix_))
{
PrepareRender(renderer);
PrepareRender(rt);
renderer->DrawImage(frame_->GetImage(), &frame_->GetCropRect(), nullptr);
rt->DrawImage(frame_->GetImage(), &frame_->GetCropRect(), nullptr);
}
}
}

View File

@ -77,7 +77,7 @@ namespace kiwano
void SetFrame(FramePtr frame);
// äÖČžžŤÁé
void OnRender(Renderer* renderer) override;
void OnRender(RenderTarget* rt) override;
protected:
FramePtr frame_;

View File

@ -28,7 +28,7 @@ namespace kiwano
{
stage_ = this;
SetAnchor(0, 0);
SetAnchor(Vec2{ 0, 0 });
SetSize(Renderer::GetInstance()->GetOutputSize());
}

View File

@ -200,14 +200,14 @@ namespace kiwano
style_.outline_stroke = outline_stroke;
}
void Text::OnRender(Renderer* renderer)
void Text::OnRender(RenderTarget* rt)
{
UpdateLayout();
if (text_layout_ && renderer->CheckVisibility(size_, transform_matrix_))
if (text_layout_ && rt->CheckVisibility(size_, transform_matrix_))
{
PrepareRender(renderer);
renderer->DrawTextLayout(text_layout_);
PrepareRender(rt);
rt->DrawTextLayout(text_layout_);
}
}

View File

@ -160,7 +160,7 @@ namespace kiwano
TextStyle const& style
);
void OnRender(Renderer* renderer) override;
void OnRender(RenderTarget* rt) override;
protected:
void UpdateLayout();

View File

@ -0,0 +1,49 @@
// Copyright (c) 2016-2018 Kiwano - Nomango
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "Transform.h"
namespace kiwano
{
Transform::Transform()
: position()
, rotation(0.f)
, scale(1.f, 1.f)
, skew(0.f, 0.f)
{
}
Matrix3x2 Transform::ToMatrix() const
{
if (!skew.IsOrigin())
{
return Matrix3x2::Skewing(skew) * Matrix3x2::SRT(position, scale, rotation);
}
return Matrix3x2::SRT(position, scale, rotation);
}
bool Transform::operator== (Transform const& rhs) const
{
return position == rhs.position &&
rotation == rhs.rotation &&
scale == rhs.scale &&
skew == rhs.skew;
}
}

View File

@ -19,7 +19,7 @@
// THE SOFTWARE.
#pragma once
#include "../math/Vec2.hpp"
#include "../math/math.h"
namespace kiwano
{
@ -32,19 +32,10 @@ namespace kiwano
Point skew; // ´íÇнǶÈ
public:
Transform()
: position()
, rotation(0.f)
, scale(1.f, 1.f)
, skew(0.f, 0.f)
{}
Transform();
bool operator== (const Transform& other) const
{
return position == other.position &&
scale == other.scale &&
skew == other.skew &&
rotation == other.rotation;
}
Matrix3x2 ToMatrix() const;
bool operator== (const Transform& rhs) const;
};
}

View File

@ -37,8 +37,8 @@ namespace kiwano
, delta_()
, process_(0)
, window_size_()
, out_scene_(nullptr)
, in_scene_(nullptr)
, out_stage_(nullptr)
, in_stage_(nullptr)
, out_layer_()
, in_layer_()
{
@ -58,24 +58,21 @@ namespace kiwano
process_ = 0;
delta_ = Duration{};
out_scene_ = prev;
in_scene_ = next;
if (in_scene_)
{
Renderer::GetInstance()->CreateLayer(in_layer_);
}
if (out_scene_)
{
Renderer::GetInstance()->CreateLayer(out_layer_);
}
out_stage_ = prev;
in_stage_ = next;
window_size_ = Renderer::GetInstance()->GetOutputSize();
out_layer_.SetAreaRect(Rect{ Point(), window_size_ });
if (in_stage_)
{
in_layer_.SetAreaRect(Rect{ Point(), window_size_ });
}
if (out_stage_)
{
out_layer_.SetAreaRect(Rect{ Point(), window_size_ });
}
}
void Transition::Update(Duration dt)
{
if (duration_.IsZero())
@ -94,30 +91,30 @@ namespace kiwano
}
}
void Transition::Render(Renderer* renderer)
void Transition::Render(RenderTarget* rt)
{
if (out_scene_)
if (out_stage_)
{
renderer->SetTransform(out_scene_->GetTransformMatrix());
renderer->PushClipRect(Rect{ Point{}, window_size_ });
renderer->PushLayer(out_layer_);
out_stage_->PrepareRender(rt);
rt->PushClipRect(Rect{ Point{}, window_size_ });
rt->PushLayer(out_layer_);
out_scene_->Render(renderer);
out_stage_->Render(rt);
renderer->PopLayer();
renderer->PopClipRect();
rt->PopLayer();
rt->PopClipRect();
}
if (in_scene_)
if (in_stage_)
{
renderer->SetTransform(in_scene_->GetTransformMatrix());
renderer->PushClipRect(Rect{ Point{}, window_size_ });
renderer->PushLayer(in_layer_);
in_stage_->PrepareRender(rt);
rt->PushClipRect(Rect{ Point{}, window_size_ });
rt->PushLayer(in_layer_);
in_scene_->Render(renderer);
in_stage_->Render(rt);
renderer->PopLayer();
renderer->PopClipRect();
rt->PopLayer();
rt->PopClipRect();
}
}
@ -153,8 +150,8 @@ namespace kiwano
Rect(
window_size_.x * process_,
window_size_.y * process_,
window_size_.x * (1 - process_ * 2),
window_size_.y * (1 - process_ * 2)
window_size_.x * (1 - process_),
window_size_.y * (1 - process_)
)
);
}
@ -166,8 +163,8 @@ namespace kiwano
Rect(
window_size_.x * (1 - process_),
window_size_.y * (1 - process_),
window_size_.x * (2 * process_ - 1),
window_size_.y * (2 * process_ - 1)
window_size_.x * process_,
window_size_.y * process_
)
);
}
@ -265,16 +262,16 @@ namespace kiwano
break;
}
if (out_scene_)
if (out_stage_)
{
out_scene_->SetTransform(Transform{});
out_stage_->SetTransform(Transform{});
}
if (in_scene_)
if (in_stage_)
{
auto transform = Transform{};
transform.position = start_pos_;
in_scene_->SetTransform(transform);
in_stage_->SetTransform(transform);
}
}
@ -282,31 +279,31 @@ namespace kiwano
{
Transition::Update(dt);
if (out_scene_)
if (out_stage_)
{
auto transform = Transform{};
transform.position = pos_delta_ * process_;
out_scene_->SetTransform(transform);
out_stage_->SetTransform(transform);
}
if (in_scene_)
if (in_stage_)
{
auto transform = Transform{};
transform.position = start_pos_ + pos_delta_ * process_;
in_scene_->SetTransform(transform);
in_stage_->SetTransform(transform);
}
}
void MoveTransition::Reset()
{
if (out_scene_)
if (out_stage_)
{
out_scene_->SetTransform(Transform{});
out_stage_->SetTransform(Transform{});
}
if (in_scene_)
if (in_stage_)
{
in_scene_->SetTransform(Transform{});
in_stage_->SetTransform(Transform{});
}
}
@ -327,16 +324,16 @@ namespace kiwano
auto transform = Transform{};
transform.position = Point{ window_size_.x / 2, window_size_.y / 2 };
if (out_scene_)
if (out_stage_)
{
out_scene_->SetTransform(transform);
out_scene_->SetAnchor(0.5f, 0.5f);
out_stage_->SetTransform(transform);
out_stage_->SetAnchor(Vec2{ 0.5f, 0.5f });
}
if (in_scene_)
if (in_stage_)
{
in_scene_->SetTransform(transform);
in_scene_->SetAnchor(0.5f, 0.5f);
in_stage_->SetTransform(transform);
in_stage_->SetAnchor(Vec2{ 0.5f, 0.5f });
}
in_layer_.SetOpacity(0.f);
@ -348,42 +345,42 @@ namespace kiwano
if (process_ < .5f)
{
if (out_scene_)
if (out_stage_)
{
auto transform = out_scene_->GetTransform();
auto transform = out_stage_->GetTransform();
transform.scale = Point{ (.5f - process_) * 2, (.5f - process_) * 2 };
transform.rotation = rotation_ * (.5f - process_) * 2;
out_scene_->SetTransform(transform);
out_stage_->SetTransform(transform);
}
}
else
{
if (in_scene_)
if (in_stage_)
{
out_layer_.SetOpacity(0.f);
in_layer_.SetOpacity(1.f);
auto transform = in_scene_->GetTransform();
auto transform = in_stage_->GetTransform();
transform.scale = Point{ (process_ - .5f) * 2, (process_ - .5f) * 2 };
transform.rotation = rotation_ * (process_ - .5f) * 2;
in_scene_->SetTransform(transform);
in_stage_->SetTransform(transform);
}
}
}
void RotationTransition::Reset()
{
if (out_scene_)
if (out_stage_)
{
out_scene_->SetTransform(Transform{});
out_scene_->SetAnchor(0.f, 0.f);
out_stage_->SetTransform(Transform{});
out_stage_->SetAnchor(Vec2{ 0.f, 0.f });
}
if (in_scene_)
if (in_stage_)
{
in_scene_->SetTransform(Transform{});
in_scene_->SetAnchor(0.f, 0.f);
in_stage_->SetTransform(Transform{});
in_stage_->SetAnchor(Vec2{ 0.f, 0.f });
}
}
}

View File

@ -25,7 +25,7 @@
namespace kiwano
{
class Director;
class Renderer;
class RenderTarget;
// 舞台过渡
class KGE_API Transition
@ -50,7 +50,7 @@ namespace kiwano
virtual void Update(Duration dt);
virtual void Render(Renderer* renderer);
virtual void Render(RenderTarget* rt);
virtual void Stop();
@ -62,8 +62,8 @@ namespace kiwano
Duration duration_;
Duration delta_;
Size window_size_;
StagePtr out_scene_;
StagePtr in_scene_;
StagePtr out_stage_;
StagePtr in_stage_;
LayerArea out_layer_;
LayerArea in_layer_;
};

View File

@ -45,7 +45,7 @@ namespace kiwano
void ActionGroup::Init(ActorPtr target)
{
if (actions_.item_empty())
if (actions_.empty())
{
Done();
return;
@ -106,7 +106,7 @@ namespace kiwano
{
if (action)
{
actions_.push_back_item(action);
actions_.push_back(action);
}
}
@ -135,7 +135,7 @@ namespace kiwano
ActionPtr ActionGroup::Reverse() const
{
auto group = new (std::nothrow) ActionGroup();
if (group && !actions_.item_empty())
if (group && !actions_.empty())
{
for (auto action = actions_.last_item(); action; action = action->prev_item())
{

View File

@ -26,7 +26,7 @@ namespace kiwano
{
void ActionManager::UpdateActions(ActorPtr target, Duration dt)
{
if (actions_.item_empty() || !target)
if (actions_.empty() || !target)
return;
ActionPtr next;
@ -38,7 +38,7 @@ namespace kiwano
action->UpdateStep(target, dt);
if (action->IsRemoveable())
actions_.remove_item(action);
actions_.remove(action);
}
}
@ -48,14 +48,14 @@ namespace kiwano
if (action)
{
actions_.push_back_item(action);
actions_.push_back(action);
}
return action.get();
}
ActionPtr ActionManager::GetAction(String const & name)
{
if (actions_.item_empty())
if (actions_.empty())
return nullptr;
for (auto action = actions_.first_item().get(); action; action = action->next_item().get())
@ -66,7 +66,7 @@ namespace kiwano
void ActionManager::ResumeAllActions()
{
if (actions_.item_empty())
if (actions_.empty())
return;
for (auto action = actions_.first_item().get(); action; action = action->next_item().get())
@ -77,7 +77,7 @@ namespace kiwano
void ActionManager::PauseAllActions()
{
if (actions_.item_empty())
if (actions_.empty())
return;
for (auto action = actions_.first_item().get(); action; action = action->next_item().get())
@ -88,7 +88,7 @@ namespace kiwano
void ActionManager::StopAllActions()
{
if (actions_.item_empty())
if (actions_.empty())
return;
for (auto action = actions_.first_item().get(); action; action = action->next_item().get())

View File

@ -281,7 +281,7 @@ namespace kiwano
void ActionScaleBy::UpdateTween(ActorPtr target, Float32 percent)
{
target->SetScale(start_scale_x_ + delta_x_ * percent, start_scale_y_ + delta_y_ * percent);
target->SetScale(Vec2{ start_scale_x_ + delta_x_ * percent, start_scale_y_ + delta_y_ * percent });
}
ActionPtr ActionScaleBy::Clone() const

View File

@ -25,7 +25,7 @@
namespace kiwano
{
class Renderer;
class RenderTarget;
class KGE_API Component
{
@ -38,7 +38,7 @@ namespace kiwano
virtual void AfterUpdate() {}
virtual void BeforeRender() {}
virtual void OnRender(Renderer*) {}
virtual void OnRender(RenderTarget*) {}
virtual void AfterRender() {}
virtual void HandleEvent(Event&) {}

View File

@ -23,6 +23,7 @@
#include "../2d/Stage.h"
#include "../2d/Transition.h"
#include "../2d/DebugActor.h"
#include "../renderer/RenderTarget.h"
namespace kiwano
{
@ -35,34 +36,34 @@ namespace kiwano
{
}
void Director::EnterStage(StagePtr scene)
void Director::EnterStage(StagePtr stage)
{
KGE_ASSERT(scene && "Director::EnterStage failed, NULL pointer exception");
KGE_ASSERT(stage && "Director::EnterStage failed, NULL pointer exception");
if (curr_scene_ == scene || next_scene_ == scene)
if (curr_stage_ == stage || next_stage_ == stage)
return;
next_scene_ = scene;
next_stage_ = stage;
}
void Director::EnterStage(StagePtr scene, TransitionPtr transition)
void Director::EnterStage(StagePtr stage, TransitionPtr transition)
{
EnterStage(scene);
EnterStage(stage);
if (transition && next_scene_)
if (transition && next_stage_)
{
if (transition_)
{
transition_->Stop();
}
transition_ = transition;
transition_->Init(curr_scene_, next_scene_);
transition_->Init(curr_stage_, next_stage_);
}
}
StagePtr Director::GetCurrentStage()
{
return curr_scene_;
return curr_stage_;
}
void Director::SetRenderBorderEnabled(bool enabled)
@ -85,8 +86,8 @@ namespace kiwano
void Director::ClearStages()
{
curr_scene_.reset();
next_scene_.reset();
curr_stage_.reset();
next_stage_.reset();
debug_actor_.reset();
transition_.reset();
}
@ -101,54 +102,52 @@ namespace kiwano
transition_ = nullptr;
}
if (next_scene_ && !transition_)
if (next_stage_ && !transition_)
{
if (curr_scene_)
if (curr_stage_)
{
curr_scene_->OnExit();
curr_stage_->OnExit();
}
next_scene_->OnEnter();
next_stage_->OnEnter();
curr_scene_ = next_scene_;
next_scene_ = nullptr;
curr_stage_ = next_stage_;
next_stage_ = nullptr;
}
if (curr_scene_)
curr_scene_->Update(dt);
if (curr_stage_)
curr_stage_->Update(dt);
if (next_scene_)
next_scene_->Update(dt);
if (next_stage_)
next_stage_->Update(dt);
if (debug_actor_)
debug_actor_->Update(dt);
}
void Director::OnRender(Renderer* renderer)
void Director::OnRender(RenderTarget* rt)
{
if (transition_)
{
transition_->Render(renderer);
transition_->Render(rt);
}
else if (curr_scene_)
else if (curr_stage_)
{
curr_scene_->Render(renderer);
curr_stage_->Render(rt);
}
if (render_border_enabled_)
{
rt->SetOpacity(1.f);
if (curr_stage_)
{
curr_stage_->RenderBorder(rt);
}
}
if (debug_actor_)
{
debug_actor_->Render(renderer);
}
}
void Director::AfterRender()
{
if (render_border_enabled_)
{
if (curr_scene_)
{
curr_scene_->RenderBorder();
}
debug_actor_->Render(rt);
}
}
@ -157,8 +156,8 @@ namespace kiwano
if (debug_actor_)
debug_actor_->Dispatch(evt);
if (curr_scene_)
curr_scene_->Dispatch(evt);
if (curr_stage_)
curr_stage_->Dispatch(evt);
}
}

View File

@ -35,12 +35,12 @@ namespace kiwano
public:
// 切换舞台
void EnterStage(
StagePtr scene /* Îę̀ */
StagePtr stage /* Îę̀ */
);
// 切换舞台
void EnterStage(
StagePtr scene, /* Îę̀ */
StagePtr stage, /* Îę̀ */
TransitionPtr transition /* 过渡动画 */
);
@ -63,9 +63,7 @@ namespace kiwano
void OnUpdate(Duration dt) override;
void OnRender(Renderer* renderer) override;
void AfterRender() override;
void OnRender(RenderTarget* rt) override;
void HandleEvent(Event& evt) override;
@ -76,8 +74,8 @@ namespace kiwano
protected:
bool render_border_enabled_;
StagePtr curr_scene_;
StagePtr next_scene_;
StagePtr curr_stage_;
StagePtr next_stage_;
ActorPtr debug_actor_;
TransitionPtr transition_;
};

View File

@ -25,7 +25,7 @@ namespace kiwano
{
void EventDispatcher::Dispatch(Event& evt)
{
if (listeners_.item_empty())
if (listeners_.empty())
return;
EventListenerPtr next;
@ -46,7 +46,7 @@ namespace kiwano
if (listener)
{
listeners_.push_back_item(listener);
listeners_.push_back(listener);
}
return listener;
}
@ -56,7 +56,7 @@ namespace kiwano
EventListenerPtr listener = new EventListener(type, callback, name);
if (listener)
{
listeners_.push_back_item(listener);
listeners_.push_back(listener);
}
}
@ -91,7 +91,7 @@ namespace kiwano
if (listener->IsName(listener_name))
{
listeners_.remove_item(listener);
listeners_.remove(listener);
}
}
}
@ -127,7 +127,7 @@ namespace kiwano
if (listener->type_ == type)
{
listeners_.remove_item(listener);
listeners_.remove(listener);
}
}
}

View File

@ -25,7 +25,7 @@ namespace kiwano
{
void TimerManager::UpdateTimers(Duration dt)
{
if (timers_.item_empty())
if (timers_.empty())
return;
TimerPtr next;
@ -37,7 +37,7 @@ namespace kiwano
timer->Update(dt, remove_after_update);
if (remove_after_update)
timers_.remove_item(timer);
timers_.remove(timer);
}
}
@ -48,13 +48,13 @@ namespace kiwano
if (timer)
{
timer->Reset();
timers_.push_back_item(timer);
timers_.push_back(timer);
}
}
void TimerManager::StopTimers(String const& name)
{
if (timers_.item_empty())
if (timers_.empty())
return;
for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get())
@ -68,7 +68,7 @@ namespace kiwano
void TimerManager::StartTimers(String const& name)
{
if (timers_.item_empty())
if (timers_.empty())
return;
for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get())
@ -82,7 +82,7 @@ namespace kiwano
void TimerManager::RemoveTimers(String const& name)
{
if (timers_.item_empty())
if (timers_.empty())
return;
TimerPtr next;
@ -91,14 +91,14 @@ namespace kiwano
next = timer->next_item();
if (timer->IsName(name))
{
timers_.remove_item(timer);
timers_.remove(timer);
}
}
}
void TimerManager::StopAllTimers()
{
if (timers_.item_empty())
if (timers_.empty())
return;
for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get())
@ -109,7 +109,7 @@ namespace kiwano
void TimerManager::StartAllTimers()
{
if (timers_.item_empty())
if (timers_.empty())
return;
for (auto timer = timers_.first_item().get(); timer; timer = timer->next_item().get())
@ -120,7 +120,7 @@ namespace kiwano
void TimerManager::RemoveAllTimers()
{
timers_.clear_items();
timers_.clear();
}
const TimerManager::Timers & TimerManager::GetAllTimers() const

View File

@ -73,7 +73,7 @@ public:
intrusive_list() : first_(), last_() {}
~intrusive_list() { clear_items(); }
~intrusive_list() { clear(); }
T const& first_item() const { return first_; }
@ -83,9 +83,9 @@ public:
T& last_item() { return last_; }
bool item_empty() const { return !first_; }
bool empty() const { return !first_; }
void push_back_item(T const& child)
void push_back(T const& child)
{
if (child->prev_)
child->prev_->next_ = child->next_;
@ -109,7 +109,7 @@ public:
KGE_DEBUG_CHECK_LIST(this);
}
void push_front_item(T const& child)
void push_front(T const& child)
{
if (child->prev_)
child->prev_->next_ = child->next_;
@ -171,7 +171,7 @@ public:
KGE_DEBUG_CHECK_LIST(this);
}
void remove_item(T const& child)
void remove(T const& child)
{
#ifdef KGE_DEBUG_ENABLE_LIST_CHECK
T tmp = first_;
@ -206,7 +206,7 @@ public:
KGE_DEBUG_CHECK_LIST(this);
}
void clear_items()
void clear()
{
T p = first_;
while (p)

View File

@ -95,7 +95,7 @@
//
#include "2d/Transform.hpp"
#include "2d/Transform.h"
#include "2d/TextStyle.hpp"
#include "2d/Frame.h"

View File

@ -172,7 +172,7 @@ namespace kiwano
value_type top = std::min(std::min(top_left.y, top_right.y), std::min(bottom_left.y, bottom_right.y));
value_type bottom = std::max(std::max(top_left.y, top_right.y), std::max(bottom_left.y, bottom_right.y));
return rect_type{ left, top, (right - left), (bottom - top) };
return rect_type{ left, top, right, bottom };
}
inline void Translate(const vec2_type& v)
@ -324,8 +324,3 @@ namespace kiwano
}
}
}
namespace kiwano
{
using Matrix3x2 = kiwano::math::Matrix3x2T<Float32>;
}

View File

@ -25,100 +25,105 @@ namespace kiwano
{
namespace math
{
// 矩形
template <typename _Ty>
struct RectT
{
public:
using value_type = _Ty;
Vec2T<value_type> origin; // 左上角坐标
Vec2T<value_type> size; // 宽度和高度
Vec2T<value_type> left_top;
Vec2T<value_type> right_bottom;
public:
RectT() {}
RectT(
value_type x,
value_type y,
value_type width,
value_type height
value_type left,
value_type top,
value_type right,
value_type bottom
)
: origin(x, y)
, size(width, height)
: left_top(left, top)
, right_bottom(right, bottom)
{}
RectT(
const Vec2T<value_type>& pos,
const Vec2T<value_type>& size
const Vec2T<value_type>& left_top,
const Vec2T<value_type>& right_bottom
)
: origin(pos.x, pos.y)
, size(size.x, size.y)
: left_top(left_top)
, right_bottom(right_bottom)
{}
RectT(
const RectT& other
)
: origin(other.origin.x, other.origin.y)
, size(other.size.x, other.size.y)
: left_top(other.left_top)
, right_bottom(other.right_bottom)
{}
RectT& operator= (const RectT& other)
{
origin = other.origin;
size = other.size;
left_top = other.left_top;
right_bottom = other.right_bottom;
return *this;
}
inline bool operator== (const RectT& rect) const
{
return (origin == rect.origin) && (size == rect.size);
return (left_top == rect.left_top) && (right_bottom == rect.right_bottom);
}
inline void Set(value_type x, value_type y, value_type width, value_type height)
inline void Set(value_type left, value_type top, value_type right, value_type bottom)
{
origin = Vec2T<value_type>{ x, y };
size = Vec2T<value_type>{ width, height };
left_top = Vec2T<value_type>{ left, top };
right_bottom = Vec2T<value_type>{ right, bottom };
}
inline Vec2T<value_type> GetCenter() const { return Vec2T<value_type>{ origin.x + size.x / 2, origin.y + size.y / 2 }; }
inline Vec2T<value_type> GetCenter() const { return Vec2T<value_type>{ (left_top.x + right_bottom.x) / 2, (left_top.y + right_bottom.y) / 2 }; }
inline Vec2T<value_type> GetLeftTop() const { return origin; }
inline Vec2T<value_type> GetLeftTop() const { return left_top; }
inline Vec2T<value_type> GetRightBottom() const { return Vec2T<value_type>{ GetRight(), GetBottom() }; }
inline Vec2T<value_type> GetRightBottom() const { return right_bottom; }
inline Vec2T<value_type> GetRightTop() const { return Vec2T<value_type>{ GetRight(), GetTop() }; }
inline Vec2T<value_type> GetRightTop() const { return Vec2T<value_type>{ right_bottom.x, left_top.y }; }
inline Vec2T<value_type> GetLeftBottom() const { return Vec2T<value_type>{ GetLeft(), GetBottom() }; }
inline Vec2T<value_type> GetLeftBottom() const { return Vec2T<value_type>{ left_top.x, right_bottom.y }; }
inline value_type GetLeft() const { return origin.x; }
inline value_type GetLeft() const { return left_top.x; }
inline value_type GetTop() const { return origin.y; }
inline value_type GetTop() const { return left_top.y; }
inline value_type GetRight() const { return origin.x + size.x; }
inline value_type GetRight() const { return right_bottom.x; }
inline value_type GetBottom() const { return origin.y + size.y; }
inline value_type GetBottom() const { return right_bottom.y; }
inline bool IsEmpty() const { return origin.IsOrigin() && size.IsOrigin(); }
inline value_type GetWidth() const { return right_bottom.x - left_top.x; }
inline value_type GetHeight() const { return right_bottom.y - left_top.y; }
inline Vec2T<value_type> GetSize() const { return Vec2T<value_type>{ GetWidth(), GetHeight() }; }
inline bool IsEmpty() const { return left_top.IsOrigin() && right_bottom.IsOrigin(); }
inline bool ContainsPoint(const Vec2T<value_type>& point) const
{
return point.x >= origin.x && point.x <= (origin.x + size.x) &&
point.y >= origin.y && point.y <= (origin.y + size.y);
return point.x >= left_top.x && point.x <= right_bottom.x &&
point.y >= left_top.y && point.y <= right_bottom.y;
}
inline bool Intersects(const RectT& rect) const
{
return !((origin.x + size.x) < rect.origin.x ||
(rect.origin.x + rect.size.x) < origin.x ||
(origin.y + size.y) < rect.origin.y ||
(rect.origin.y + rect.size.y) < origin.y);
return !(right_bottom.x < rect.left_top.x ||
rect.right_bottom.x < left_top.x ||
right_bottom.y < rect.left_top.y ||
rect.right_bottom.y < left_top.y);
}
static inline RectT Infinite()
{
return RectT{ -math::constants::FLOAT_MAX, -math::constants::FLOAT_MAX, math::constants::FLOAT_MAX, math::constants::FLOAT_MAX };
}
};
}
}
namespace kiwano
{
using Rect = kiwano::math::RectT<Float32>;
}

View File

@ -120,8 +120,3 @@ namespace kiwano
};
}
}
namespace kiwano
{
using Vec2 = kiwano::math::Vec2T<Float32>;
}

View File

@ -26,13 +26,16 @@ namespace kiwano
{
namespace constants
{
const auto PI_F = 3.141592653589793f;
const auto PI_F_2 = 1.570796326794896f;
const auto PI_F_X_2 = 6.283185307179586f;
constexpr auto PI_F = 3.141592653589793f;
constexpr auto PI_F_2 = 1.570796326794896f;
constexpr auto PI_F_X_2 = 6.283185307179586f;
const auto PI_D = 3.14159265358979323846;
const auto PI_D_2 = 1.57079632679489661923;
const auto PI_D_X_2 = 6.28318530717958647692;
constexpr auto PI_D = 3.14159265358979323846;
constexpr auto PI_D_2 = 1.57079632679489661923;
constexpr auto PI_D_X_2 = 6.28318530717958647692;
constexpr auto FLOAT_MAX = 3.402823466e+38F;
constexpr auto FLOAT_MIN = 1.175494351e-38F;
}
}
}

View File

@ -19,6 +19,7 @@
// THE SOFTWARE.
#pragma once
#include "..\core\core.h"
#include "constants.hpp"
#include "ease.hpp"
#include "scalar.hpp"
@ -28,6 +29,10 @@
namespace kiwano
{
using Vec2 = kiwano::math::Vec2T<Float32>;
using Rect = kiwano::math::RectT<Float32>;
using Matrix3x2 = kiwano::math::Matrix3x2T<Float32>;
using Point = Vec2;
using Size = Vec2;
}

View File

@ -22,7 +22,6 @@
#include "constants.hpp"
#include <cmath>
namespace kiwano
{
namespace math

View File

@ -43,10 +43,10 @@ namespace kiwano
if (!geo_)
return Rect{};
D2D1_RECT_F rect;
Rect rect;
// no matter it failed or not
geo_->GetBounds(DX::ConvertToMatrix3x2F(transform), &rect);
return Rect{ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top };
geo_->GetBounds(DX::ConvertToMatrix3x2F(transform), DX::ConvertToRectF(&rect));
return rect;
}
Float32 Geometry::GetLength()

View File

@ -317,7 +317,7 @@ namespace kiwano
hr = (prop_val.vt == VT_UI2 ? S_OK : E_FAIL);
if (SUCCEEDED(hr))
{
frame_rect.origin.x = static_cast<Float32>(prop_val.uiVal);
frame_rect.left_top.x = static_cast<Float32>(prop_val.uiVal);
}
PropVariantClear(&prop_val);
}
@ -331,7 +331,7 @@ namespace kiwano
hr = (prop_val.vt == VT_UI2 ? S_OK : E_FAIL);
if (SUCCEEDED(hr))
{
frame_rect.origin.y = static_cast<Float32>(prop_val.uiVal);
frame_rect.left_top.y = static_cast<Float32>(prop_val.uiVal);
}
PropVariantClear(&prop_val);
}
@ -345,7 +345,7 @@ namespace kiwano
hr = (prop_val.vt == VT_UI2 ? S_OK : E_FAIL);
if (SUCCEEDED(hr))
{
frame_rect.size.x = static_cast<Float32>(prop_val.uiVal);
frame_rect.right_bottom.x = frame_rect.left_top.x + static_cast<Float32>(prop_val.uiVal);
}
PropVariantClear(&prop_val);
}
@ -359,7 +359,7 @@ namespace kiwano
hr = (prop_val.vt == VT_UI2 ? S_OK : E_FAIL);
if (SUCCEEDED(hr))
{
frame_rect.size.y = static_cast<Float32>(prop_val.uiVal);
frame_rect.right_bottom.y = frame_rect.left_top.y + static_cast<Float32>(prop_val.uiVal);
}
PropVariantClear(&prop_val);
}

View File

@ -24,6 +24,7 @@ namespace kiwano
{
LayerArea::LayerArea()
: opacity_(1.f)
, area_(Rect::Infinite())
{
}

View File

@ -35,16 +35,24 @@ namespace kiwano
inline Rect const& GetAreaRect() const { return area_; }
inline void SetAreaRect(Rect const& area) { area_ = area; }
inline Float32 GetOpacity() const { return opacity_; }
inline void SetOpacity(Float32 opacity) { opacity_ = opacity; }
inline Geometry const& GetMaskGeometry() const { return mask_; }
inline Matrix3x2 const& GetMaskTransform() const { return mask_transform_; }
// <20>零暠꿔혐堵
inline void SetAreaRect(Rect const& area) { area_ = area; }
// <20>零暠꿔拷츠똑
inline void SetOpacity(Float32 opacity) { opacity_ = opacity; }
// <20>零섯부촁꿔
inline void SetMaskGeometry(Geometry const& mask) { mask_ = mask; }
// <20>零섯부촁꿔긴뻣
inline void SetMaskTransform(Matrix3x2 const& matrix) { mask_transform_ = matrix; }
public:
inline ComPtr<ID2D1Layer> GetLayer() const { return layer_; }
@ -54,6 +62,7 @@ namespace kiwano
Rect area_;
Float32 opacity_;
Geometry mask_;
Matrix3x2 mask_transform_;
ComPtr<ID2D1Layer> layer_;
};
}

View File

@ -36,14 +36,14 @@ namespace kiwano
status_.primitives = 0;
}
HRESULT RenderTarget::InitDeviceResources(ComPtr<ID2D1RenderTarget> rt, ComPtr<ID2DDeviceResources> dev_res)
HRESULT RenderTarget::CreateDeviceResources(ComPtr<ID2D1RenderTarget> rt, ComPtr<ID2DDeviceResources> dev_res)
{
HRESULT hr = E_FAIL;
if (rt && dev_res)
{
render_target_ = rt;
d2d_res_ = dev_res;
device_resources_ = dev_res;
hr = S_OK;
}
@ -58,20 +58,29 @@ namespace kiwano
if (SUCCEEDED(hr))
{
solid_color_brush_.reset();
default_brush_.reset();
hr = render_target_->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::White),
D2D1::BrushProperties(),
&solid_color_brush_
&default_brush_
);
}
return hr;
}
void RenderTarget::DiscardDeviceResources()
{
text_renderer_.reset();
render_target_.reset();
default_brush_.reset();
current_brush_.reset();
device_resources_.reset();
}
bool RenderTarget::IsValid() const
{
return render_target_ && d2d_res_;
return render_target_ && device_resources_;
}
void RenderTarget::BeginDraw()
@ -111,20 +120,20 @@ namespace kiwano
) const
{
HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_)
if (!default_brush_ || !render_target_)
{
hr = E_UNEXPECTED;
}
if (SUCCEEDED(hr) && geometry.GetGeometry())
{
solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color));
default_brush_->SetColor(DX::ConvertToColorF(stroke_color));
render_target_->DrawGeometry(
geometry.GetGeometry().get(),
solid_color_brush_.get(),
default_brush_.get(),
stroke_width,
d2d_res_->GetStrokeStyle(stroke)
device_resources_->GetStrokeStyle(stroke)
);
IncreasePrimitivesCount();
@ -136,17 +145,17 @@ namespace kiwano
void RenderTarget::FillGeometry(Geometry const& geometry, Color const& fill_color) const
{
HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_)
if (!default_brush_ || !render_target_)
{
hr = E_UNEXPECTED;
}
if (SUCCEEDED(hr) && geometry.GetGeometry())
{
solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color));
default_brush_->SetColor(DX::ConvertToColorF(fill_color));
render_target_->FillGeometry(
geometry.GetGeometry().get(),
solid_color_brush_.get()
default_brush_.get()
);
}
@ -156,21 +165,21 @@ namespace kiwano
void RenderTarget::DrawLine(Point const& point1, Point const& point2, Color const& stroke_color, Float32 stroke_width, StrokeStyle stroke) const
{
HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_)
if (!default_brush_ || !render_target_)
{
hr = E_UNEXPECTED;
}
if (SUCCEEDED(hr))
{
solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color));
default_brush_->SetColor(DX::ConvertToColorF(stroke_color));
render_target_->DrawLine(
DX::ConvertToPoint2F(point1),
DX::ConvertToPoint2F(point2),
solid_color_brush_.get(),
default_brush_.get(),
stroke_width,
d2d_res_->GetStrokeStyle(stroke)
device_resources_->GetStrokeStyle(stroke)
);
IncreasePrimitivesCount();
@ -182,20 +191,20 @@ namespace kiwano
void RenderTarget::DrawRectangle(Rect const& rect, Color const& stroke_color, Float32 stroke_width, StrokeStyle stroke) const
{
HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_)
if (!default_brush_ || !render_target_)
{
hr = E_UNEXPECTED;
}
if (SUCCEEDED(hr))
{
solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color));
default_brush_->SetColor(DX::ConvertToColorF(stroke_color));
render_target_->DrawRectangle(
DX::ConvertToRectF(rect),
solid_color_brush_.get(),
default_brush_.get(),
stroke_width,
d2d_res_->GetStrokeStyle(stroke)
device_resources_->GetStrokeStyle(stroke)
);
IncreasePrimitivesCount();
@ -207,17 +216,17 @@ namespace kiwano
void RenderTarget::FillRectangle(Rect const& rect, Color const& fill_color) const
{
HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_)
if (!default_brush_ || !render_target_)
{
hr = E_UNEXPECTED;
}
if (SUCCEEDED(hr))
{
solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color));
default_brush_->SetColor(DX::ConvertToColorF(fill_color));
render_target_->FillRectangle(
DX::ConvertToRectF(rect),
solid_color_brush_.get()
default_brush_.get()
);
}
@ -227,14 +236,14 @@ namespace kiwano
void RenderTarget::DrawRoundedRectangle(Rect const& rect, Vec2 const& radius, Color const& stroke_color, Float32 stroke_width, StrokeStyle stroke) const
{
HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_)
if (!default_brush_ || !render_target_)
{
hr = E_UNEXPECTED;
}
if (SUCCEEDED(hr))
{
solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color));
default_brush_->SetColor(DX::ConvertToColorF(stroke_color));
render_target_->DrawRoundedRectangle(
D2D1::RoundedRect(
@ -242,9 +251,9 @@ namespace kiwano
radius.x,
radius.y
),
solid_color_brush_.get(),
default_brush_.get(),
stroke_width,
d2d_res_->GetStrokeStyle(stroke)
device_resources_->GetStrokeStyle(stroke)
);
IncreasePrimitivesCount();
@ -256,21 +265,21 @@ namespace kiwano
void RenderTarget::FillRoundedRectangle(Rect const& rect, Vec2 const& radius, Color const& fill_color) const
{
HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_)
if (!default_brush_ || !render_target_)
{
hr = E_UNEXPECTED;
}
if (SUCCEEDED(hr))
{
solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color));
default_brush_->SetColor(DX::ConvertToColorF(fill_color));
render_target_->FillRoundedRectangle(
D2D1::RoundedRect(
DX::ConvertToRectF(rect),
radius.x,
radius.y
),
solid_color_brush_.get()
default_brush_.get()
);
}
@ -280,14 +289,14 @@ namespace kiwano
void RenderTarget::DrawEllipse(Point const& center, Vec2 const& radius, Color const& stroke_color, Float32 stroke_width, StrokeStyle stroke) const
{
HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_)
if (!default_brush_ || !render_target_)
{
hr = E_UNEXPECTED;
}
if (SUCCEEDED(hr))
{
solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color));
default_brush_->SetColor(DX::ConvertToColorF(stroke_color));
render_target_->DrawEllipse(
D2D1::Ellipse(
@ -295,9 +304,9 @@ namespace kiwano
radius.x,
radius.y
),
solid_color_brush_.get(),
default_brush_.get(),
stroke_width,
d2d_res_->GetStrokeStyle(stroke)
device_resources_->GetStrokeStyle(stroke)
);
IncreasePrimitivesCount();
@ -309,21 +318,21 @@ namespace kiwano
void RenderTarget::FillEllipse(Point const& center, Vec2 const& radius, Color const& fill_color) const
{
HRESULT hr = S_OK;
if (!solid_color_brush_ || !render_target_)
if (!default_brush_ || !render_target_)
{
hr = E_UNEXPECTED;
}
if (SUCCEEDED(hr))
{
solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color));
default_brush_->SetColor(DX::ConvertToColorF(fill_color));
render_target_->FillEllipse(
D2D1::Ellipse(
DX::ConvertToPoint2F(center),
radius.x,
radius.y
),
solid_color_brush_.get()
default_brush_.get()
);
}
@ -375,7 +384,7 @@ namespace kiwano
layout.GetTextStyle().outline,
DX::ConvertToColorF(layout.GetTextStyle().outline_color),
layout.GetTextStyle().outline_width,
d2d_res_->GetStrokeStyle(layout.GetTextStyle().outline_stroke)
device_resources_->GetStrokeStyle(layout.GetTextStyle().outline_stroke)
);
}
@ -447,14 +456,19 @@ namespace kiwano
ThrowIfFailed(hr);
}
void RenderTarget::PushLayer(LayerArea const& layer)
void RenderTarget::PushLayer(LayerArea& layer)
{
HRESULT hr = S_OK;
if (!render_target_ || !solid_color_brush_)
if (!render_target_ || !default_brush_)
{
hr = E_UNEXPECTED;
}
if (!layer.IsValid())
{
CreateLayer(layer);
}
if (SUCCEEDED(hr) && layer.IsValid())
{
render_target_->PushLayer(
@ -462,7 +476,7 @@ namespace kiwano
DX::ConvertToRectF(layer.GetAreaRect()),
layer.GetMaskGeometry().GetGeometry().get(),
antialias_ ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED,
D2D1::Matrix3x2F::Identity(),
DX::ConvertToMatrix3x2F(layer.GetMaskTransform()),
layer.GetOpacity(),
nullptr,
D2D1_LAYER_OPTIONS_NONE
@ -540,7 +554,7 @@ namespace kiwano
void RenderTarget::SetOpacity(Float32 opacity)
{
HRESULT hr = S_OK;
if (!solid_color_brush_)
if (!default_brush_)
{
hr = E_UNEXPECTED;
}
@ -550,7 +564,7 @@ namespace kiwano
if (opacity_ != opacity)
{
opacity_ = opacity;
solid_color_brush_->SetOpacity(opacity);
default_brush_->SetOpacity(opacity);
}
}
@ -611,6 +625,13 @@ namespace kiwano
ThrowIfFailed(hr);
}
bool RenderTarget::CheckVisibility(Size const& content_size, Matrix3x2 const& transform)
{
return Rect{ Point{}, reinterpret_cast<const Size&>(render_target_->GetSize()) }.Intersects(
transform.Transform(Rect{ Point{}, content_size })
);
}
void RenderTarget::SetCollectingStatus(bool collecting)
{
collecting_status_ = collecting;
@ -633,28 +654,29 @@ namespace kiwano
{
}
void ImageRenderTarget::GetOutput(Image& output) const
Image ImageRenderTarget::GetOutput() const
{
HRESULT hr = E_FAIL;
ComPtr<ID2D1BitmapRenderTarget> bitmap_rt;
if (render_target_)
{
ComPtr<ID2D1BitmapRenderTarget> bitmap_rt;
hr = render_target_->QueryInterface<ID2D1BitmapRenderTarget>(&bitmap_rt);
}
if (SUCCEEDED(hr))
{
ComPtr<ID2D1Bitmap> bitmap;
if (SUCCEEDED(hr))
{
hr = bitmap_rt->GetBitmap(&bitmap);
}
if (SUCCEEDED(hr))
{
output.SetBitmap(bitmap);
return Image(bitmap);
}
}
}
ThrowIfFailed(hr);
return Image();
}
}

View File

@ -33,6 +33,8 @@ namespace kiwano
: public noncopyable
{
public:
bool IsValid() const;
void BeginDraw();
void EndDraw();
@ -125,7 +127,7 @@ namespace kiwano
void PopClipRect();
void PushLayer(
LayerArea const& layer
LayerArea& layer
);
void PopLayer();
@ -156,6 +158,11 @@ namespace kiwano
TextAntialias mode
);
bool CheckVisibility(
Size const& content_size,
Matrix3x2 const& transform
);
public:
struct Status
{
@ -170,17 +177,19 @@ namespace kiwano
inline Status const& GetStatus() const { return status_; }
inline ComPtr<ID2D1RenderTarget> GetRenderTarget() const { return render_target_; }
inline ComPtr<ID2D1RenderTarget> GetRenderTarget() const { KGE_ASSERT(render_target_); return render_target_; }
inline ComPtr<ITextRenderer> GetTextRenderer() const { KGE_ASSERT(text_renderer_); return text_renderer_; }
public:
RenderTarget();
HRESULT InitDeviceResources(
HRESULT CreateDeviceResources(
ComPtr<ID2D1RenderTarget> rt,
ComPtr<ID2DDeviceResources> dev_res
);
bool IsValid() const;
void DiscardDeviceResources();
protected:
Float32 opacity_;
@ -188,10 +197,11 @@ namespace kiwano
mutable bool collecting_status_;
mutable Status status_;
TextAntialias text_antialias_;
ComPtr<ID2D1RenderTarget> render_target_;
ComPtr<ITextRenderer> text_renderer_;
ComPtr<ID2D1SolidColorBrush> solid_color_brush_;
ComPtr<ID2DDeviceResources> d2d_res_;
ComPtr<ID2D1RenderTarget> render_target_;
ComPtr<ID2D1SolidColorBrush> default_brush_;
ComPtr<ID2D1Brush> current_brush_;
ComPtr<ID2DDeviceResources> device_resources_;
};
@ -202,6 +212,6 @@ namespace kiwano
public:
ImageRenderTarget();
void GetOutput(Image& output) const;
Image GetOutput() const;
};
}

View File

@ -126,6 +126,8 @@ namespace kiwano
{
KGE_LOG(L"Destroying device resources");
RenderTarget::DiscardDeviceResources();
d2d_res_->GetDWriteFactory()->UnregisterFontFileLoader(res_font_file_loader_.get());
res_font_file_loader_.reset();
@ -133,7 +135,6 @@ namespace kiwano
res_font_collection_loader_.reset();
drawing_state_block_.reset();
solid_color_brush_.reset();
d2d_res_.reset();
d3d_res_.reset();
}
@ -208,7 +209,9 @@ namespace kiwano
HRESULT Renderer::CreateDeviceResources()
{
HRESULT hr = InitDeviceResources(
KGE_ASSERT(d2d_res_);
HRESULT hr = RenderTarget::CreateDeviceResources(
d2d_res_->GetDeviceContext(),
d2d_res_
);
@ -656,7 +659,7 @@ namespace kiwano
if (SUCCEEDED(hr))
{
hr = render_target.InitDeviceResources(output, d2d_res_);
hr = render_target.CreateDeviceResources(output, d2d_res_);
}
ThrowIfFailed(hr);
@ -690,11 +693,4 @@ namespace kiwano
clear_color_ = color;
}
bool Renderer::CheckVisibility(Size const& content_size, Matrix3x2 const& transform)
{
return Rect{ Point{}, output_size_ }.Intersects(
transform.Transform(Rect{ Point{}, content_size })
);
}
}

View File

@ -136,11 +136,6 @@ namespace kiwano
UInt32 height
);
bool CheckVisibility(
Size const& content_size,
Matrix3x2 const& transform
);
public:
void SetupComponent() override;
@ -161,10 +156,6 @@ namespace kiwano
inline ID3DDeviceResources* GetD3DDeviceResources() const { KGE_ASSERT(d3d_res_); return d3d_res_.get(); }
inline ITextRenderer* GetTextRenderer() const { KGE_ASSERT(text_renderer_); return text_renderer_.get(); }
inline ID2D1SolidColorBrush* GetSolidColorBrush() const { KGE_ASSERT(solid_color_brush_); return solid_color_brush_.get(); }
private:
Renderer();

View File

@ -101,16 +101,31 @@ namespace kiwano
}
//
// SizeF
// RectF
//
inline D2D1_RECT_F ConvertToRectF(Rect const& rect)
inline D2D1_RECT_F const& ConvertToRectF(Rect const& rect)
{
return D2D1_RECT_F{ rect.origin.x, rect.origin.y, rect.origin.x + rect.size.x, rect.origin.y + rect.size.y };
return reinterpret_cast<D2D1_RECT_F const&>(rect);
}
inline D2D1_RECT_F& ConvertToRectF(Rect& rect)
{
return reinterpret_cast<D2D1_RECT_F&>(rect);
}
inline const D2D1_RECT_F* ConvertToRectF(const Rect* rect)
{
return reinterpret_cast<const D2D1_RECT_F*>(rect);
}
inline D2D1_RECT_F* ConvertToRectF(Rect* rect)
{
return reinterpret_cast<D2D1_RECT_F*>(rect);
}
//
// SizeF
// ColorF
//
inline D2D1_COLOR_F const& ConvertToColorF(Color const& color)
{
@ -133,7 +148,7 @@ namespace kiwano
}
//
// SizeF
// MatrixF
//
inline D2D1_MATRIX_3X2_F const& ConvertToMatrix3x2F(Matrix3x2 const& matrix)

View File

@ -119,7 +119,7 @@ namespace kiwano
{
ifs.open(file_path.c_str());
std::wstringstream ss;
StringStream ss;
ss << ifs.rdbuf();
if (tinyxml2::XML_SUCCESS != doc.Parse(ss.str().c_str()))
@ -248,7 +248,7 @@ namespace kiwano
FramePtr ptr = new (std::nothrow) Frame(raw->GetImage());
if (ptr)
{
ptr->SetCropRect(Rect{ j * width, i * height, width, height });
ptr->SetCropRect(Rect{ j * width, i * height, (j + 1) * width, (i + 1) * height });
image_arr.push_back(ptr);
}
}