diff --git a/src/kiwano-imgui/src/ImGuiLayer.cpp b/src/kiwano-imgui/src/ImGuiLayer.cpp index 32029175..63f2b55f 100644 --- a/src/kiwano-imgui/src/ImGuiLayer.cpp +++ b/src/kiwano-imgui/src/ImGuiLayer.cpp @@ -33,8 +33,9 @@ namespace kiwano { } - void ImGuiLayer::OnRender() + void ImGuiLayer::OnRender(Renderer* renderer) { + PrepareRender(renderer); for (const auto& pipeline : pipelines_) { pipeline.second(); diff --git a/src/kiwano-imgui/src/ImGuiLayer.h b/src/kiwano-imgui/src/ImGuiLayer.h index 72477508..7f057185 100644 --- a/src/kiwano-imgui/src/ImGuiLayer.h +++ b/src/kiwano-imgui/src/ImGuiLayer.h @@ -52,7 +52,7 @@ namespace kiwano void RemoveAllItems(); public: - void OnRender() override; + void OnRender(Renderer* renderer) override; protected: Map pipelines_; diff --git a/src/kiwano/2d/Actor.cpp b/src/kiwano/2d/Actor.cpp index 3b162827..455ef8c5 100644 --- a/src/kiwano/2d/Actor.cpp +++ b/src/kiwano/2d/Actor.cpp @@ -82,7 +82,7 @@ namespace kiwano } } - void Actor::Render() + void Actor::Render(Renderer* renderer) { if (!visible_) return; @@ -91,8 +91,7 @@ namespace kiwano if (children_.is_empty()) { - PrepareRender(); - OnRender(); + OnRender(renderer); } else { @@ -103,21 +102,26 @@ namespace kiwano if (child->GetZOrder() >= 0) break; - child->Render(); + child->Render(renderer); child = child->next_item().get(); } - PrepareRender(); - OnRender(); + OnRender(renderer); while (child) { - child->Render(); + child->Render(renderer); child = child->next_item().get(); } } } + void Actor::PrepareRender(Renderer* renderer) + { + renderer->SetTransform(transform_matrix_); + renderer->SetOpacity(displayed_opacity_); + } + void Actor::RenderBorder() { if (show_border_) @@ -656,12 +660,4 @@ namespace kiwano return GetBounds().ContainsPoint(local); } - - void VisualActor::PrepareRender() - { - auto renderer = Renderer::GetInstance(); - renderer->SetTransform(transform_matrix_); - renderer->SetOpacity(displayed_opacity_); - } - } diff --git a/src/kiwano/2d/Actor.h b/src/kiwano/2d/Actor.h index 0075b65b..d71d5217 100644 --- a/src/kiwano/2d/Actor.h +++ b/src/kiwano/2d/Actor.h @@ -28,6 +28,7 @@ namespace kiwano { class Director; + class Renderer; // 角色 class KGE_API Actor @@ -51,7 +52,7 @@ namespace kiwano virtual void OnUpdate(Duration dt) { KGE_UNUSED(dt); } // 渲染角色 - virtual void OnRender() {} + virtual void OnRender(Renderer* renderer) { KGE_UNUSED(renderer); } // 获取显示状态 bool IsVisible() const { return visible_; } @@ -135,10 +136,10 @@ namespace kiwano Transform GetTransform() const { return transform_; } // 获取边框 - Rect GetBounds() const; + virtual Rect GetBounds() const; // 获取外切包围盒 - Rect GetBoundingBox() const; + virtual Rect GetBoundingBox() const; // 获取二维变换矩阵 Matrix const& GetTransformMatrix() const; @@ -379,6 +380,9 @@ namespace kiwano // 从父角色移除 void RemoveFromParent(); + // 事件分发 + void Dispatch(Event& evt) override; + // 暂停角色更新 inline void PauseUpdating() { update_pausing_ = true; } @@ -403,16 +407,12 @@ namespace kiwano float anchor_y ); - public: - // 事件分发 - void Dispatch(Event& evt) override; - protected: - virtual void PrepareRender() {} - virtual void Update(Duration dt); - virtual void Render(); + virtual void Render(Renderer* renderer); + + void PrepareRender(Renderer* renderer); void RenderBorder(); @@ -451,14 +451,4 @@ namespace kiwano mutable Matrix transform_matrix_inverse_; }; - - // 可视角色 - // 在渲染前处理二维旋转矩阵和透明度 - class KGE_API VisualActor - : public Actor - { - public: - virtual void PrepareRender() override; - }; - } diff --git a/src/kiwano/2d/Canvas.cpp b/src/kiwano/2d/Canvas.cpp index 623cdbfc..8bb6d660 100644 --- a/src/kiwano/2d/Canvas.cpp +++ b/src/kiwano/2d/Canvas.cpp @@ -86,7 +86,7 @@ namespace kiwano cache_expired_ = true; } - void Canvas::OnRender() + void Canvas::OnRender(Renderer* renderer) { if (cache_expired_) { @@ -95,8 +95,10 @@ namespace kiwano if (bitmap_cached_) { + PrepareRender(renderer); + Rect bitmap_rect(0.f, 0.f, bitmap_cached_->GetSize().width, bitmap_cached_->GetSize().height); - Renderer::GetInstance()->DrawBitmap( + renderer->DrawBitmap( bitmap_cached_, bitmap_rect, bitmap_rect diff --git a/src/kiwano/2d/Canvas.h b/src/kiwano/2d/Canvas.h index 4defcae0..59fb2b98 100644 --- a/src/kiwano/2d/Canvas.h +++ b/src/kiwano/2d/Canvas.h @@ -33,7 +33,7 @@ namespace kiwano { // 画布 class KGE_API Canvas - : public VisualActor + : public Actor { public: Canvas(); @@ -211,7 +211,7 @@ namespace kiwano // 导出为图片 ImagePtr ExportToImage() const; - void OnRender() override; + void OnRender(Renderer* renderer) override; protected: ComPtr const& GetBitmap() const; diff --git a/src/kiwano/2d/DebugActor.cpp b/src/kiwano/2d/DebugActor.cpp index 604c172a..aaef5c99 100644 --- a/src/kiwano/2d/DebugActor.cpp +++ b/src/kiwano/2d/DebugActor.cpp @@ -28,7 +28,7 @@ namespace kiwano { - DebugNode::DebugNode() + DebugActor::DebugActor() : background_color_(0.0f, 0.0f, 0.0f, 0.7f) { SetName(L"kiwano-debug-actor"); @@ -54,13 +54,13 @@ namespace kiwano AddListener(Event::MouseOut, [=](const Event&) { SetOpacity(1.f); }); } - DebugNode::~DebugNode() + DebugActor::~DebugActor() { } - void DebugNode::OnRender() + void DebugActor::OnRender(Renderer* renderer) { - auto renderer = Renderer::GetInstance(); + PrepareRender(renderer); renderer->GetSolidColorBrush()->SetColor(DX::ConvertToColorF(background_color_)); renderer->GetD2DDeviceResources()->GetDeviceContext()->FillRoundedRectangle( @@ -69,7 +69,7 @@ namespace kiwano ); } - void DebugNode::OnUpdate(Duration dt) + void DebugActor::OnUpdate(Duration dt) { KGE_UNUSED(dt); diff --git a/src/kiwano/2d/DebugActor.h b/src/kiwano/2d/DebugActor.h index 519868c5..771758d2 100644 --- a/src/kiwano/2d/DebugActor.h +++ b/src/kiwano/2d/DebugActor.h @@ -23,15 +23,15 @@ namespace kiwano { - class KGE_API DebugNode - : public VisualActor + class KGE_API DebugActor + : public Actor { public: - DebugNode(); + DebugActor(); - virtual ~DebugNode(); + virtual ~DebugActor(); - void OnRender() override; + void OnRender(Renderer* renderer) override; void OnUpdate(Duration dt) override; diff --git a/src/kiwano/2d/GifSprite.cpp b/src/kiwano/2d/GifSprite.cpp index f63d7e90..de4bb118 100644 --- a/src/kiwano/2d/GifSprite.cpp +++ b/src/kiwano/2d/GifSprite.cpp @@ -86,7 +86,7 @@ namespace kiwano void GifSprite::Update(Duration dt) { - VisualActor::Update(dt); + Actor::Update(dt); if (image_ && animating_) { @@ -100,12 +100,14 @@ namespace kiwano } } - void GifSprite::OnRender() + void GifSprite::OnRender(Renderer* renderer) { - if (frame_to_render_) + if (frame_to_render_ && renderer->CheckVisibility(size_, transform_matrix_)) { + PrepareRender(renderer); + Rect bounds = GetBounds(); - Renderer::GetInstance()->DrawBitmap(frame_to_render_, bounds, bounds); + renderer->DrawBitmap(frame_to_render_, bounds, bounds); } } diff --git a/src/kiwano/2d/GifSprite.h b/src/kiwano/2d/GifSprite.h index a0d05fa3..c72ddc28 100644 --- a/src/kiwano/2d/GifSprite.h +++ b/src/kiwano/2d/GifSprite.h @@ -27,7 +27,7 @@ namespace kiwano { class KGE_API GifSprite - : public VisualActor + : public Actor { public: using LoopDoneCallback = Function; @@ -67,7 +67,7 @@ namespace kiwano inline DoneCallback GetDoneCallback() const { return done_cb_; } - void OnRender() override; + void OnRender(Renderer* renderer) override; protected: void Update(Duration dt) override; diff --git a/src/kiwano/2d/ShapeActor.cpp b/src/kiwano/2d/ShapeActor.cpp index 068de12e..8939ebda 100644 --- a/src/kiwano/2d/ShapeActor.cpp +++ b/src/kiwano/2d/ShapeActor.cpp @@ -41,7 +41,7 @@ namespace kiwano { } - Rect ShapeActor::GetBoundingBox() + Rect ShapeActor::GetBounds() const { if (!geo_) return Rect{}; @@ -52,6 +52,17 @@ namespace kiwano return Rect{ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top }; } + Rect ShapeActor::GetBoundingBox() const + { + if (!geo_) + return Rect{}; + + D2D1_RECT_F rect; + // no matter it failed or not + geo_->GetBounds(DX::ConvertToMatrix3x2F(transform_matrix_), &rect); + return Rect{ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top }; + } + float ShapeActor::GetLength() { float length = 0.f; @@ -125,16 +136,18 @@ namespace kiwano outline_join_ = outline_join; } - void ShapeActor::OnRender() + void ShapeActor::OnRender(Renderer* renderer) { if (geo_) { - Renderer::GetInstance()->FillGeometry( + PrepareRender(renderer); + + renderer->FillGeometry( geo_, fill_color_ ); - Renderer::GetInstance()->DrawGeometry( + renderer->DrawGeometry( geo_, stroke_color_, stroke_width_, diff --git a/src/kiwano/2d/ShapeActor.h b/src/kiwano/2d/ShapeActor.h index cc7d450c..25498b2e 100644 --- a/src/kiwano/2d/ShapeActor.h +++ b/src/kiwano/2d/ShapeActor.h @@ -26,7 +26,7 @@ namespace kiwano { // 二维图形角色 class KGE_API ShapeActor - : public VisualActor + : public Actor { public: ShapeActor(); @@ -49,8 +49,11 @@ namespace kiwano // 获取线条相交样式 StrokeStyle SetOutlineJoinStyle() const { return outline_join_; } + // 获取边界 + Rect GetBounds() const override; + // 获取外切包围盒 - Rect GetBoundingBox(); + Rect GetBoundingBox() const override; // 判断图形是否包含点 bool ContainsPoint( @@ -96,7 +99,7 @@ namespace kiwano // 获取形状 inline ComPtr GetGeometry() const { return geo_; } - void OnRender() override; + void OnRender(Renderer* renderer) override; protected: Color fill_color_; diff --git a/src/kiwano/2d/Sprite.cpp b/src/kiwano/2d/Sprite.cpp index 1ca2abfa..301747aa 100644 --- a/src/kiwano/2d/Sprite.cpp +++ b/src/kiwano/2d/Sprite.cpp @@ -83,11 +83,12 @@ namespace kiwano } } - void Sprite::OnRender() + void Sprite::OnRender(Renderer* renderer) { - if (frame_) + if (frame_ && renderer->CheckVisibility(size_, transform_matrix_)) { - Renderer::GetInstance()->DrawBitmap(frame_->GetImage()->GetBitmap(), frame_->GetCropRect(), GetBounds()); + PrepareRender(renderer); + renderer->DrawBitmap(frame_->GetImage()->GetBitmap(), frame_->GetCropRect(), GetBounds()); } } } diff --git a/src/kiwano/2d/Sprite.h b/src/kiwano/2d/Sprite.h index 350f73ad..01940df6 100644 --- a/src/kiwano/2d/Sprite.h +++ b/src/kiwano/2d/Sprite.h @@ -26,7 +26,7 @@ namespace kiwano { // 精灵 class KGE_API Sprite - : public VisualActor + : public Actor { public: Sprite(); @@ -63,7 +63,7 @@ namespace kiwano void SetFrame(FramePtr frame); // 渲染精灵 - void OnRender() override; + void OnRender(Renderer* renderer) override; protected: FramePtr frame_; diff --git a/src/kiwano/2d/Text.cpp b/src/kiwano/2d/Text.cpp index 288ddcba..1c36567a 100644 --- a/src/kiwano/2d/Text.cpp +++ b/src/kiwano/2d/Text.cpp @@ -297,14 +297,14 @@ namespace kiwano style_.outline_stroke = outline_stroke; } - void Text::OnRender() + void Text::OnRender(Renderer* renderer) { UpdateLayout(); - if (text_layout_) + if (text_layout_ && renderer->CheckVisibility(layout_size_, transform_matrix_)) { - auto renderer = Renderer::GetInstance(); - renderer->SetTextStyle( + PrepareRender(renderer); + renderer->SetTextStyle( GetDisplayedOpacity(), style_.color, style_.outline, diff --git a/src/kiwano/2d/Text.h b/src/kiwano/2d/Text.h index dc74aa6e..d2c07ce3 100644 --- a/src/kiwano/2d/Text.h +++ b/src/kiwano/2d/Text.h @@ -28,7 +28,7 @@ namespace kiwano { // 文本 class KGE_API Text - : public VisualActor + : public Actor { public: Text(); @@ -203,7 +203,7 @@ namespace kiwano TextStyle const& style ); - void OnRender() override; + void OnRender(Renderer* renderer) override; protected: void UpdateLayout() const; @@ -218,4 +218,4 @@ namespace kiwano mutable ComPtr text_format_; mutable ComPtr text_layout_; }; -} \ No newline at end of file +} diff --git a/src/kiwano/2d/Transition.cpp b/src/kiwano/2d/Transition.cpp index 29187e31..2693bad5 100644 --- a/src/kiwano/2d/Transition.cpp +++ b/src/kiwano/2d/Transition.cpp @@ -99,10 +99,8 @@ namespace kiwano } } - void Transition::Render() + void Transition::Render(Renderer* renderer) { - auto renderer = Renderer::GetInstance(); - if (out_scene_) { renderer->PushClip( @@ -111,7 +109,7 @@ namespace kiwano ); renderer->PushLayer(out_layer_, out_layer_prop_); - out_scene_->Render(); + out_scene_->Render(renderer); renderer->PopLayer(); renderer->PopClip(); @@ -125,7 +123,7 @@ namespace kiwano ); renderer->PushLayer(in_layer_, in_layer_prop_); - in_scene_->Render(); + in_scene_->Render(renderer); renderer->PopLayer(); renderer->PopClip(); diff --git a/src/kiwano/2d/Transition.h b/src/kiwano/2d/Transition.h index d25f992a..63cd9642 100644 --- a/src/kiwano/2d/Transition.h +++ b/src/kiwano/2d/Transition.h @@ -25,6 +25,7 @@ namespace kiwano { class Director; + class Renderer; // 舞台过渡 class KGE_API Transition @@ -49,7 +50,7 @@ namespace kiwano virtual void Update(Duration dt); - virtual void Render(); + virtual void Render(Renderer* renderer); virtual void Stop(); diff --git a/src/kiwano/base/Component.h b/src/kiwano/base/Component.h index cb753b58..0628e93e 100644 --- a/src/kiwano/base/Component.h +++ b/src/kiwano/base/Component.h @@ -25,6 +25,8 @@ namespace kiwano { + class Renderer; + class KGE_API Component { public: @@ -36,7 +38,7 @@ namespace kiwano virtual void AfterUpdate() {} virtual void BeforeRender() {} - virtual void OnRender() {} + virtual void OnRender(Renderer*) {} virtual void AfterRender() {} virtual void HandleEvent(Event&) {} diff --git a/src/kiwano/base/Director.cpp b/src/kiwano/base/Director.cpp index 50b4ac45..89ee9fe4 100644 --- a/src/kiwano/base/Director.cpp +++ b/src/kiwano/base/Director.cpp @@ -75,7 +75,7 @@ namespace kiwano if (show) { if (!debug_actor_) - debug_actor_ = new DebugNode; + debug_actor_ = new DebugActor; } else { @@ -124,19 +124,21 @@ namespace kiwano debug_actor_->Update(dt); } - void Director::OnRender() + void Director::OnRender(Renderer* renderer) { if (transition_) { - transition_->Render(); + transition_->Render(renderer); } else if (curr_scene_) { - curr_scene_->Render(); + curr_scene_->Render(renderer); } if (debug_actor_) - debug_actor_->Render(); + { + debug_actor_->Render(renderer); + } } void Director::AfterRender() diff --git a/src/kiwano/base/Director.h b/src/kiwano/base/Director.h index 03b2c6d8..2b96f617 100644 --- a/src/kiwano/base/Director.h +++ b/src/kiwano/base/Director.h @@ -63,7 +63,7 @@ namespace kiwano void OnUpdate(Duration dt) override; - void OnRender() override; + void OnRender(Renderer* renderer) override; void AfterRender() override; diff --git a/src/kiwano/platform/Application.cpp b/src/kiwano/platform/Application.cpp index e4f9e57c..da311c13 100644 --- a/src/kiwano/platform/Application.cpp +++ b/src/kiwano/platform/Application.cpp @@ -267,9 +267,10 @@ namespace kiwano } // Rendering + Renderer* renderer = Renderer::GetInstance(); for (Component* c : components_) { - c->OnRender(); + c->OnRender(renderer); } // After render diff --git a/src/kiwano/renderer/render.cpp b/src/kiwano/renderer/render.cpp index 2441d554..5867d3a9 100644 --- a/src/kiwano/renderer/render.cpp +++ b/src/kiwano/renderer/render.cpp @@ -484,4 +484,11 @@ namespace kiwano return S_OK; } + bool Renderer::CheckVisibility(Size const& content_size, Matrix const& transform) + { + return Rect{ Point{}, output_size_ }.Intersects( + transform.Transform(Rect{ Point{}, content_size }) + ); + } + } diff --git a/src/kiwano/renderer/render.h b/src/kiwano/renderer/render.h index 4bbce81c..6b6a3dbe 100644 --- a/src/kiwano/renderer/render.h +++ b/src/kiwano/renderer/render.h @@ -147,6 +147,11 @@ namespace kiwano UINT height ); + bool CheckVisibility( + Size const& content_size, + Matrix const& transform + ); + public: void SetupComponent() override;