From bd58cf1b493de195279e4dd446a990f4844c0e20 Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Tue, 13 Aug 2019 14:44:37 +0800 Subject: [PATCH 01/11] Add ImageCache, add ResourceCache, add Frame, rename Frames to FrameSequence --- projects/kiwano.vcxproj | 42 ++-- projects/kiwano.vcxproj.filters | 129 ++++++------ src/kiwano/2d/Actor.cpp | 9 +- src/kiwano/2d/Actor.h | 9 +- src/kiwano/2d/Canvas.cpp | 6 +- src/kiwano/2d/Canvas.h | 7 +- src/kiwano/2d/DebugNode.h | 2 +- src/kiwano/2d/Frame.cpp | 73 +++++++ src/kiwano/2d/Frame.h | 75 +++++++ .../2d/{Frames.cpp => FrameSequence.cpp} | 49 ++--- src/kiwano/2d/{Frames.h => FrameSequence.h} | 29 +-- src/kiwano/2d/GifSprite.cpp | 3 +- src/kiwano/2d/GifSprite.h | 3 +- src/kiwano/2d/Image.cpp | 184 ------------------ src/kiwano/2d/ShapeNode.h | 2 +- src/kiwano/2d/Sprite.cpp | 64 +++--- src/kiwano/2d/Sprite.h | 34 ++-- src/kiwano/2d/Text.h | 2 +- src/kiwano/2d/{ => action}/Action.cpp | 2 +- src/kiwano/2d/{ => action}/Action.h | 2 +- src/kiwano/2d/{ => action}/ActionGroup.cpp | 6 +- src/kiwano/2d/{ => action}/ActionGroup.h | 0 src/kiwano/2d/{ => action}/ActionHelper.h | 0 src/kiwano/2d/{ => action}/ActionManager.cpp | 4 +- src/kiwano/2d/{ => action}/ActionManager.h | 0 src/kiwano/2d/{ => action}/ActionTween.cpp | 3 +- src/kiwano/2d/{ => action}/ActionTween.h | 4 +- src/kiwano/2d/{ => action}/Animation.cpp | 41 ++-- src/kiwano/2d/{ => action}/Animation.h | 10 +- src/kiwano/2d/include-forwards.h | 5 +- src/kiwano/base/Resource.cpp | 4 +- src/kiwano/kiwano.h | 34 ++-- src/kiwano/math/Vec2.hpp | 4 +- src/kiwano/renderer/D2DDeviceResources.cpp | 38 +--- src/kiwano/renderer/D2DDeviceResources.h | 2 - src/kiwano/renderer/D3D10DeviceResources.cpp | 1 - src/kiwano/renderer/D3D11DeviceResources.cpp | 1 - src/kiwano/{2d => renderer}/GifImage.cpp | 1 - src/kiwano/{2d => renderer}/GifImage.h | 5 +- src/kiwano/renderer/Image.cpp | 113 +++++++++++ src/kiwano/{2d => renderer}/Image.h | 65 ++----- src/kiwano/renderer/ImageCache.cpp | 83 ++++++++ src/kiwano/renderer/ImageCache.h | 48 +++++ src/kiwano/renderer/render.cpp | 25 +-- src/kiwano/renderer/render.h | 6 +- .../{ResLoader.cpp => ResourceCache.cpp} | 154 +++++++-------- .../utils/{ResLoader.h => ResourceCache.h} | 45 ++--- 47 files changed, 786 insertions(+), 642 deletions(-) create mode 100644 src/kiwano/2d/Frame.cpp create mode 100644 src/kiwano/2d/Frame.h rename src/kiwano/2d/{Frames.cpp => FrameSequence.cpp} (63%) rename src/kiwano/2d/{Frames.h => FrameSequence.h} (75%) delete mode 100644 src/kiwano/2d/Image.cpp rename src/kiwano/2d/{ => action}/Action.cpp (99%) rename src/kiwano/2d/{ => action}/Action.h (99%) rename src/kiwano/2d/{ => action}/ActionGroup.cpp (98%) rename src/kiwano/2d/{ => action}/ActionGroup.h (100%) rename src/kiwano/2d/{ => action}/ActionHelper.h (100%) rename src/kiwano/2d/{ => action}/ActionManager.cpp (98%) rename src/kiwano/2d/{ => action}/ActionManager.h (100%) rename src/kiwano/2d/{ => action}/ActionTween.cpp (99%) rename src/kiwano/2d/{ => action}/ActionTween.h (99%) rename src/kiwano/2d/{ => action}/Animation.cpp (71%) rename src/kiwano/2d/{ => action}/Animation.h (90%) rename src/kiwano/{2d => renderer}/GifImage.cpp (99%) rename src/kiwano/{2d => renderer}/GifImage.h (97%) create mode 100644 src/kiwano/renderer/Image.cpp rename src/kiwano/{2d => renderer}/Image.h (63%) create mode 100644 src/kiwano/renderer/ImageCache.cpp create mode 100644 src/kiwano/renderer/ImageCache.h rename src/kiwano/utils/{ResLoader.cpp => ResourceCache.cpp} (64%) rename src/kiwano/utils/{ResLoader.h => ResourceCache.h} (69%) diff --git a/projects/kiwano.vcxproj b/projects/kiwano.vcxproj index 9d80d8fb..1cba2a48 100644 --- a/projects/kiwano.vcxproj +++ b/projects/kiwano.vcxproj @@ -1,6 +1,13 @@ + + + + + + + @@ -8,20 +15,12 @@ - - - - - - - + - - @@ -70,7 +69,10 @@ + + + @@ -80,22 +82,21 @@ - + - - - - - + + + + + - + + - - @@ -119,6 +120,9 @@ + + + @@ -128,7 +132,7 @@ - + diff --git a/projects/kiwano.vcxproj.filters b/projects/kiwano.vcxproj.filters index f98d06cf..0233eb9b 100644 --- a/projects/kiwano.vcxproj.filters +++ b/projects/kiwano.vcxproj.filters @@ -34,6 +34,9 @@ {0cae76f7-7016-4a45-bb26-a130fbce8024} + + {9314f30d-5742-48b6-94e5-e3b4284106f6} + @@ -42,24 +45,6 @@ ui - - 2d - - - 2d - - - 2d - - - 2d - - - 2d - - - 2d - 2d @@ -72,12 +57,6 @@ 2d - - 2d - - - 2d - 2d @@ -186,9 +165,6 @@ utils - - utils - @@ -222,9 +198,6 @@ base - - 2d - third-party\StackWalker @@ -270,6 +243,42 @@ 2d + + 2d + + + renderer + + + renderer + + + 2d\action + + + 2d\action + + + 2d\action + + + 2d\action + + + 2d\action + + + 2d\action + + + renderer + + + utils + + + 2d + @@ -278,21 +287,6 @@ ui - - 2d - - - 2d - - - 2d - - - 2d - - - 2d - 2d @@ -302,12 +296,6 @@ 2d - - 2d - - - 2d - 2d @@ -359,9 +347,6 @@ utils - - utils - base @@ -383,9 +368,6 @@ base - - 2d - third-party\StackWalker @@ -410,5 +392,38 @@ 2d + + 2d + + + renderer + + + renderer + + + 2d\action + + + 2d\action + + + 2d\action + + + 2d\action + + + 2d\action + + + renderer + + + utils + + + 2d + \ No newline at end of file diff --git a/src/kiwano/2d/Actor.cpp b/src/kiwano/2d/Actor.cpp index 9efd36df..a44868c4 100644 --- a/src/kiwano/2d/Actor.cpp +++ b/src/kiwano/2d/Actor.cpp @@ -19,7 +19,6 @@ // THE SOFTWARE. #include "Actor.h" -#include "Action.h" #include "Stage.h" #include "../base/logs.h" #include "../renderer/render.h" @@ -658,11 +657,11 @@ namespace kiwano } - void VisualNode::PrepareRender() + void VisualActor::PrepareRender() { - auto renderer = Renderer::Instance(); - renderer->SetTransform(transform_matrix_); - renderer->SetOpacity(displayed_opacity_); + auto renderer = Renderer::Instance(); + renderer->SetTransform(transform_matrix_); + renderer->SetOpacity(displayed_opacity_); } } diff --git a/src/kiwano/2d/Actor.h b/src/kiwano/2d/Actor.h index 9f0f5427..e5b096f6 100644 --- a/src/kiwano/2d/Actor.h +++ b/src/kiwano/2d/Actor.h @@ -21,7 +21,7 @@ #pragma once #include "include-forwards.h" #include "Transform.hpp" -#include "ActionManager.h" +#include "action/ActionManager.h" #include "../base/TimerManager.h" #include "../base/EventDispatcher.h" @@ -77,7 +77,7 @@ namespace kiwano // 获取 y 坐标 float GetPositionY() const { return transform_.position.y; } - // 获取横向缩放比例 + // 获取缩放比例 Point GetScale() const { return transform_.scale; } // 获取横向缩放比例 @@ -452,8 +452,9 @@ namespace kiwano }; - // 可视化角色 - class KGE_API VisualNode + // 可视角色 + // 在渲染前处理二维旋转矩阵和透明度 + class KGE_API VisualActor : public Actor { public: diff --git a/src/kiwano/2d/Canvas.cpp b/src/kiwano/2d/Canvas.cpp index be985f0d..ebb6032b 100644 --- a/src/kiwano/2d/Canvas.cpp +++ b/src/kiwano/2d/Canvas.cpp @@ -19,7 +19,6 @@ // THE SOFTWARE. #include "Canvas.h" -#include "Image.h" #include "../base/logs.h" #include "../renderer/render.h" @@ -258,7 +257,7 @@ namespace kiwano D2D1::RectF(0, 0, image->GetWidth(), image->GetHeight()), opacity, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, - DX::ConvertToRectF(image->GetCropRect()) + D2D1::RectF(0, 0, image->GetWidth(), image->GetHeight()) ); cache_expired_ = true; } @@ -463,8 +462,7 @@ namespace kiwano ImagePtr Canvas::ExportToImage() const { - auto image = new Image(GetBitmap()); - image->Crop(Rect(Point{}, this->GetSize())); + ImagePtr image = new Image(GetBitmap()); return image; } diff --git a/src/kiwano/2d/Canvas.h b/src/kiwano/2d/Canvas.h index 3af235d2..210558a0 100644 --- a/src/kiwano/2d/Canvas.h +++ b/src/kiwano/2d/Canvas.h @@ -22,15 +22,18 @@ #include "Actor.h" #include "Font.hpp" #include "TextStyle.hpp" +#include "../renderer/Image.h" #include "../renderer/TextRenderer.h" -#undef DrawText +#ifdef DrawText +# undef DrawText +#endif namespace kiwano { // 画布 class KGE_API Canvas - : public VisualNode + : public VisualActor { public: Canvas(); diff --git a/src/kiwano/2d/DebugNode.h b/src/kiwano/2d/DebugNode.h index 32988ef7..320448a1 100644 --- a/src/kiwano/2d/DebugNode.h +++ b/src/kiwano/2d/DebugNode.h @@ -24,7 +24,7 @@ namespace kiwano { class KGE_API DebugNode - : public VisualNode + : public VisualActor { public: DebugNode(); diff --git a/src/kiwano/2d/Frame.cpp b/src/kiwano/2d/Frame.cpp new file mode 100644 index 00000000..e3874078 --- /dev/null +++ b/src/kiwano/2d/Frame.cpp @@ -0,0 +1,73 @@ +// 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 "Frame.h" +#include "../renderer/ImageCache.h" + +namespace kiwano +{ + Frame::Frame() + { + } + + Frame::Frame(Resource const& res) + { + Load(res); + } + + Frame::Frame(ImagePtr image) + : image_(image) + { + } + + bool Frame::Load(Resource const& res) + { + ImagePtr image = ImageCache::Instance()->AddImage(res); + if (image && image->IsValid()) + { + SetImage(image); + return true; + } + return false; + } + + void Frame::Crop(Rect const& crop_rect) + { + if (image_) + { + 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); + } + } + + void Frame::SetImage(ImagePtr image) + { + image_ = image; + if (image_) + { + crop_rect_.origin.x = crop_rect_.origin.y = 0; + crop_rect_.size.x = image_->GetWidth(); + crop_rect_.size.y = image_->GetHeight(); + } + } +} diff --git a/src/kiwano/2d/Frame.h b/src/kiwano/2d/Frame.h new file mode 100644 index 00000000..360cfd63 --- /dev/null +++ b/src/kiwano/2d/Frame.h @@ -0,0 +1,75 @@ +// 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. + +#pragma once +#include "../renderer/Image.h" + +namespace kiwano +{ + // 帧图像 + class KGE_API Frame + : public Object + { + public: + Frame(); + + explicit Frame( + Resource const& res + ); + + explicit Frame( + ImagePtr image + ); + + bool Load( + Resource const& res + ); + + // 裁剪矩形 + void Crop( + Rect const& crop_rect /* 裁剪矩形 */ + ); + + // 获取宽度 + float GetWidth() const { return crop_rect_.size.x; } + + // 获取高度 + float GetHeight() const { return crop_rect_.size.y; } + + // 获取大小 + Size GetSize() const { return crop_rect_.size; } + + // 获取裁剪位置 + Point GetCropPoint() const { return crop_rect_.origin; } + + // 获取裁剪矩形 + inline Rect const& GetCropRect() const { return crop_rect_; } + + // 获取位图 + inline ImagePtr GetImage() const { return image_; } + + // 设置位图 + void SetImage(ImagePtr image); + + protected: + ImagePtr image_; + Rect crop_rect_; + }; +} diff --git a/src/kiwano/2d/Frames.cpp b/src/kiwano/2d/FrameSequence.cpp similarity index 63% rename from src/kiwano/2d/Frames.cpp rename to src/kiwano/2d/FrameSequence.cpp index 549946dc..99ef1a12 100644 --- a/src/kiwano/2d/Frames.cpp +++ b/src/kiwano/2d/FrameSequence.cpp @@ -18,28 +18,28 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include "Frames.h" -#include "Image.h" +#include "FrameSequence.h" +#include "Frame.h" #include "../base/logs.h" namespace kiwano { - Frames::Frames() + FrameSequence::FrameSequence() { } - Frames::Frames(Array const& frames) + FrameSequence::FrameSequence(Array const& frames) { - this->Add(frames); + this->AddFrames(frames); } - Frames::~Frames() + FrameSequence::~FrameSequence() { } - void Frames::Add(ImagePtr frame) + void FrameSequence::AddFrame(FramePtr frame) { - KGE_ASSERT(frame && "Frames::Add failed, NULL pointer exception"); + KGE_ASSERT(frame && "FrameSequence::Add failed, NULL pointer exception"); if (frame) { @@ -47,7 +47,7 @@ namespace kiwano } } - void Frames::Add(Array const& frames) + void FrameSequence::AddFrames(Array const& frames) { if (frames_.empty()) frames_ = frames; @@ -55,40 +55,43 @@ namespace kiwano { frames_.reserve(frames_.size() + frames.size()); for (const auto& image : frames) - Add(image); + AddFrame(image); } } - Array const& Frames::GetFrames() const + FramePtr FrameSequence::GetFrame(size_t index) const + { + KGE_ASSERT(index < frames_.size()); + return frames_[index]; + } + + Array const& FrameSequence::GetFrames() const { return frames_; } - FramesPtr Frames::Clone() const + FrameSequencePtr FrameSequence::Clone() const { - auto animation = new (std::nothrow) Frames; - if (animation) + auto frame_seq = new (std::nothrow) FrameSequence; + if (frame_seq) { - for (const auto& frame : frames_) - { - animation->Add(frame); - } + frame_seq->AddFrames(frames_); } - return animation; + return frame_seq; } - FramesPtr Frames::Reverse() const + FrameSequencePtr FrameSequence::Reverse() const { - auto animation = new (std::nothrow) Frames; + auto frame_seq = new (std::nothrow) FrameSequence; if (!frames_.empty()) { for (auto iter = frames_.crbegin(), crend = frames_.crend(); iter != crend; ++iter) { if (*iter) - animation->Add(*iter); + frame_seq->AddFrame(*iter); } } - return animation; + return frame_seq; } } diff --git a/src/kiwano/2d/Frames.h b/src/kiwano/2d/FrameSequence.h similarity index 75% rename from src/kiwano/2d/Frames.h rename to src/kiwano/2d/FrameSequence.h index 11eabe32..373e22b8 100644 --- a/src/kiwano/2d/Frames.h +++ b/src/kiwano/2d/FrameSequence.h @@ -24,38 +24,41 @@ namespace kiwano { // 序列帧 - class KGE_API Frames + class KGE_API FrameSequence : public Object { public: - Frames(); + FrameSequence(); - explicit Frames( - Array const& frames /* 序列帧 */ + explicit FrameSequence( + Array const& frames /* 帧序列 */ ); - virtual ~Frames(); + virtual ~FrameSequence(); // 添加关键帧 - void Add( - ImagePtr frame + void AddFrame( + FramePtr frame ); // 添加多个关键帧 - void Add( - Array const& frames + void AddFrames( + Array const& frames ); // 获取关键帧 - Array const& GetFrames() const; + FramePtr GetFrame(size_t index) const; + + // 获取关键帧 + Array const& GetFrames() const; // 获取帧动画的拷贝对象 - FramesPtr Clone() const; + FrameSequencePtr Clone() const; // 获取帧动画的倒转 - FramesPtr Reverse() const; + FrameSequencePtr Reverse() const; protected: - Array frames_; + Array frames_; }; } diff --git a/src/kiwano/2d/GifSprite.cpp b/src/kiwano/2d/GifSprite.cpp index c007b451..c4bb7c9f 100644 --- a/src/kiwano/2d/GifSprite.cpp +++ b/src/kiwano/2d/GifSprite.cpp @@ -19,7 +19,6 @@ // THE SOFTWARE. #include "GifSprite.h" -#include "GifImage.h" #include "../base/logs.h" #include "../platform/modules.h" @@ -87,7 +86,7 @@ namespace kiwano void GifSprite::Update(Duration dt) { - VisualNode::Update(dt); + VisualActor::Update(dt); if (image_ && animating_) { diff --git a/src/kiwano/2d/GifSprite.h b/src/kiwano/2d/GifSprite.h index 5f124540..22ecd57d 100644 --- a/src/kiwano/2d/GifSprite.h +++ b/src/kiwano/2d/GifSprite.h @@ -22,11 +22,12 @@ #include "Actor.h" #include "../base/Resource.h" #include "../renderer/render.h" +#include "../renderer/GifImage.h" namespace kiwano { class KGE_API GifSprite - : public VisualNode + : public VisualActor { public: using LoopDoneCallback = Closure; diff --git a/src/kiwano/2d/Image.cpp b/src/kiwano/2d/Image.cpp deleted file mode 100644 index d4ad76a4..00000000 --- a/src/kiwano/2d/Image.cpp +++ /dev/null @@ -1,184 +0,0 @@ -// 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 "Image.h" -#include "../base/logs.h" -#include "../platform/modules.h" -#include "../utils/FileUtil.h" - -namespace kiwano -{ - Image::Image() - : bitmap_(nullptr) - , crop_rect_() - { - } - - Image::Image(Resource const& res) - : Image() - { - this->Load(res); - } - - Image::Image(Resource const& res, Rect const& crop_rect) - : Image() - { - this->Load(res); - this->Crop(crop_rect); - } - - Image::Image(ComPtr const & bitmap) - : Image() - { - SetBitmap(bitmap); - } - - Image::~Image() - { - } - - bool Image::Load(Resource const& res) - { - HRESULT hr = S_OK; - ComPtr bitmap; - - if (res.IsFileType()) - { -#if defined(KGE_DEBUG) - if (!FileUtil::ExistsFile(res.GetFileName())) - { - KGE_WARNING_LOG(L"Image file '%s' not found!", res.GetFileName().c_str()); - return false; - } -#endif - hr = Renderer::Instance()->GetD2DDeviceResources()->CreateBitmapFromFile(bitmap, res.GetFileName()); - } - else - { - hr = Renderer::Instance()->GetD2DDeviceResources()->CreateBitmapFromResource(bitmap, res); - } - - if (FAILED(hr)) - { - KGE_ERROR_LOG(L"Load image file failed with HRESULT of %08X", hr); - return false; - } - - SetBitmap(bitmap); - return true; - } - - bool Image::IsValid() const - { - return !!bitmap_; - } - - void Image::Crop(Rect const& crop_rect) - { - if (bitmap_) - { - auto bitmap_size = bitmap_->GetSize(); - crop_rect_.origin.x = std::min(std::max(crop_rect.origin.x, 0.f), bitmap_size.width); - crop_rect_.origin.y = std::min(std::max(crop_rect.origin.y, 0.f), bitmap_size.height); - crop_rect_.size.x = std::min(std::max(crop_rect.size.x, 0.f), bitmap_size.width - crop_rect.origin.x); - crop_rect_.size.y = std::min(std::max(crop_rect.size.y, 0.f), bitmap_size.height - crop_rect.origin.y); - } - } - - float Image::GetWidth() const - { - return crop_rect_.size.x; - } - - float Image::GetHeight() const - { - return crop_rect_.size.y; - } - - Size Image::GetSize() const - { - return crop_rect_.size; - } - - float Image::GetSourceWidth() const - { - if (bitmap_) - { - return bitmap_->GetSize().width; - } - return 0; - } - - float Image::GetSourceHeight() const - { - if (bitmap_) - { - return bitmap_->GetSize().height; - } - return 0; - } - - Size Image::GetSourceSize() const - { - if (bitmap_) - { - auto bitmap_size = bitmap_->GetSize(); - return Size{ bitmap_size.width, bitmap_size.height }; - } - return Size{}; - } - - float Image::GetCropX() const - { - return crop_rect_.origin.x; - } - - float Image::GetCropY() const - { - return crop_rect_.origin.y; - } - - Point Image::GetCropPos() const - { - return crop_rect_.origin; - } - - Rect Image::GetCropRect() const - { - return crop_rect_; - } - - ComPtr const& Image::GetBitmap() const - { - return bitmap_; - } - - void Image::SetBitmap(ComPtr const & bitmap) - { - if (bitmap) - { - bitmap_ = bitmap; - crop_rect_.origin.x = crop_rect_.origin.y = 0; - crop_rect_.size.x = bitmap_->GetSize().width; - crop_rect_.size.y = bitmap_->GetSize().height; - } - } - -} \ No newline at end of file diff --git a/src/kiwano/2d/ShapeNode.h b/src/kiwano/2d/ShapeNode.h index 3f9a9083..8af0a155 100644 --- a/src/kiwano/2d/ShapeNode.h +++ b/src/kiwano/2d/ShapeNode.h @@ -26,7 +26,7 @@ namespace kiwano { // 二维图形角色 class KGE_API ShapeNode - : public VisualNode + : public VisualActor { public: ShapeNode(); diff --git a/src/kiwano/2d/Sprite.cpp b/src/kiwano/2d/Sprite.cpp index 0c30462a..cae843cf 100644 --- a/src/kiwano/2d/Sprite.cpp +++ b/src/kiwano/2d/Sprite.cpp @@ -24,74 +24,70 @@ namespace kiwano { Sprite::Sprite() - : image_(nullptr) + : frame_(nullptr) { } - Sprite::Sprite(ImagePtr image) - : image_(nullptr) - { - Load(image); - } - Sprite::Sprite(Resource const& res) - : image_(nullptr) + : frame_(nullptr) { Load(res); } Sprite::Sprite(Resource const& res, const Rect& crop_rect) - : image_(nullptr) + : frame_(nullptr) { Load(res); Crop(crop_rect); } + Sprite::Sprite(FramePtr frame) + : frame_(nullptr) + { + SetFrame(frame); + } + Sprite::~Sprite() { } - bool Sprite::Load(ImagePtr image) - { - if (image && image_ != image) - { - image_ = image; - - Actor::SetSize(image_->GetWidth(), image_->GetHeight()); - return true; - } - return false; - } - bool Sprite::Load(Resource const& res) { - ImagePtr image = new (std::nothrow) Image; - if (image->Load(res)) + FramePtr frame = new (std::nothrow) Frame; + if (frame->Load(res)) { - return Load(image); + SetFrame(frame); + return true; } return false; } void Sprite::Crop(const Rect& crop_rect) { - image_->Crop(crop_rect); - Actor::SetSize( - std::min(std::max(crop_rect.size.x, 0.f), image_->GetSourceWidth() - image_->GetCropX()), - std::min(std::max(crop_rect.size.y, 0.f), image_->GetSourceHeight() - image_->GetCropY()) - ); + if (frame_) + { + frame_->Crop(crop_rect); + SetSize(frame_->GetWidth(), frame_->GetHeight()); + } } - ImagePtr Sprite::GetImage() const + void Sprite::SetFrame(FramePtr frame) { - return image_; + if (frame_ != frame) + { + frame_ = frame; + if (frame_) + { + SetSize(frame_->GetWidth(), frame_->GetHeight()); + } + } } void Sprite::OnRender() { - if (image_) + if (frame_) { - Renderer::Instance()->DrawImage(image_, GetBounds()); + Renderer::Instance()->DrawBitmap(frame_->GetImage()->GetBitmap(), frame_->GetCropRect(), GetBounds()); } } -} \ No newline at end of file +} diff --git a/src/kiwano/2d/Sprite.h b/src/kiwano/2d/Sprite.h index 3374faf2..350f73ad 100644 --- a/src/kiwano/2d/Sprite.h +++ b/src/kiwano/2d/Sprite.h @@ -20,54 +20,52 @@ #pragma once #include "Actor.h" -#include "Image.h" +#include "Frame.h" namespace kiwano { // 精灵 class KGE_API Sprite - : public VisualNode + : public VisualActor { public: Sprite(); - explicit Sprite( - ImagePtr image - ); - explicit Sprite( Resource const& res ); explicit Sprite( Resource const& res, - const Rect& crop_rect /* 裁剪矩形 */ + Rect const& crop_rect /* 裁剪矩形 */ + ); + + explicit Sprite( + FramePtr frame ); virtual ~Sprite(); - // 加载图片文件 + // 加载图像资源 bool Load( Resource const& res ); - // 加载图片 - bool Load( - ImagePtr image - ); - - // 将图片裁剪为矩形 + // 裁剪矩形 void Crop( - const Rect& crop_rect /* 裁剪矩形 */ + const Rect& crop_rect ); - // 获取 Image 对象 - ImagePtr GetImage() const; + // 获取帧图像 + inline FramePtr GetFrame() const { return frame_; } + + // 设置帧图像 + void SetFrame(FramePtr frame); // 渲染精灵 void OnRender() override; protected: - ImagePtr image_; + FramePtr frame_; }; } diff --git a/src/kiwano/2d/Text.h b/src/kiwano/2d/Text.h index 00a63ff5..dc74aa6e 100644 --- a/src/kiwano/2d/Text.h +++ b/src/kiwano/2d/Text.h @@ -28,7 +28,7 @@ namespace kiwano { // 文本 class KGE_API Text - : public VisualNode + : public VisualActor { public: Text(); diff --git a/src/kiwano/2d/Action.cpp b/src/kiwano/2d/action/Action.cpp similarity index 99% rename from src/kiwano/2d/Action.cpp rename to src/kiwano/2d/action/Action.cpp index f156283a..47b11755 100644 --- a/src/kiwano/2d/Action.cpp +++ b/src/kiwano/2d/action/Action.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "Action.h" -#include "Actor.h" +#include "../Actor.h" namespace kiwano { diff --git a/src/kiwano/2d/Action.h b/src/kiwano/2d/action/Action.h similarity index 99% rename from src/kiwano/2d/Action.h rename to src/kiwano/2d/action/Action.h index 923306ad..048b099e 100644 --- a/src/kiwano/2d/Action.h +++ b/src/kiwano/2d/action/Action.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include "include-forwards.h" +#include "../include-forwards.h" namespace kiwano { diff --git a/src/kiwano/2d/ActionGroup.cpp b/src/kiwano/2d/action/ActionGroup.cpp similarity index 98% rename from src/kiwano/2d/ActionGroup.cpp rename to src/kiwano/2d/action/ActionGroup.cpp index a4ae0588..9e3417df 100644 --- a/src/kiwano/2d/ActionGroup.cpp +++ b/src/kiwano/2d/action/ActionGroup.cpp @@ -19,8 +19,8 @@ // THE SOFTWARE. #include "ActionGroup.h" -#include "Actor.h" -#include "../base/logs.h" +#include "../Actor.h" +#include "../../base/logs.h" namespace kiwano { @@ -145,4 +145,4 @@ namespace kiwano return group; } -} \ No newline at end of file +} diff --git a/src/kiwano/2d/ActionGroup.h b/src/kiwano/2d/action/ActionGroup.h similarity index 100% rename from src/kiwano/2d/ActionGroup.h rename to src/kiwano/2d/action/ActionGroup.h diff --git a/src/kiwano/2d/ActionHelper.h b/src/kiwano/2d/action/ActionHelper.h similarity index 100% rename from src/kiwano/2d/ActionHelper.h rename to src/kiwano/2d/action/ActionHelper.h diff --git a/src/kiwano/2d/ActionManager.cpp b/src/kiwano/2d/action/ActionManager.cpp similarity index 98% rename from src/kiwano/2d/ActionManager.cpp rename to src/kiwano/2d/action/ActionManager.cpp index 5bf7fa2c..855f725f 100644 --- a/src/kiwano/2d/ActionManager.cpp +++ b/src/kiwano/2d/action/ActionManager.cpp @@ -19,8 +19,8 @@ // THE SOFTWARE. #include "ActionManager.h" -#include "Actor.h" -#include "../base/logs.h" +#include "../Actor.h" +#include "../../base/logs.h" namespace kiwano { diff --git a/src/kiwano/2d/ActionManager.h b/src/kiwano/2d/action/ActionManager.h similarity index 100% rename from src/kiwano/2d/ActionManager.h rename to src/kiwano/2d/action/ActionManager.h diff --git a/src/kiwano/2d/ActionTween.cpp b/src/kiwano/2d/action/ActionTween.cpp similarity index 99% rename from src/kiwano/2d/ActionTween.cpp rename to src/kiwano/2d/action/ActionTween.cpp index 279be38d..7f7c2cf6 100644 --- a/src/kiwano/2d/ActionTween.cpp +++ b/src/kiwano/2d/action/ActionTween.cpp @@ -19,8 +19,7 @@ // THE SOFTWARE. #include "ActionTween.h" -#include "include-forwards.h" -#include "Actor.h" +#include "../Actor.h" namespace kiwano { diff --git a/src/kiwano/2d/ActionTween.h b/src/kiwano/2d/action/ActionTween.h similarity index 99% rename from src/kiwano/2d/ActionTween.h rename to src/kiwano/2d/action/ActionTween.h index 230eee75..5516446a 100644 --- a/src/kiwano/2d/ActionTween.h +++ b/src/kiwano/2d/action/ActionTween.h @@ -20,8 +20,8 @@ #pragma once #include "Action.h" -#include "../base/logs.h" -#include "../renderer/render.h" // ID2D1PathGeometry, ID2D1GeometrySink +#include "../../base/logs.h" +#include "../../renderer/render.h" // ID2D1PathGeometry, ID2D1GeometrySink namespace kiwano { diff --git a/src/kiwano/2d/Animation.cpp b/src/kiwano/2d/action/Animation.cpp similarity index 71% rename from src/kiwano/2d/Animation.cpp rename to src/kiwano/2d/action/Animation.cpp index 6576923c..ed260f30 100644 --- a/src/kiwano/2d/Animation.cpp +++ b/src/kiwano/2d/action/Animation.cpp @@ -19,50 +19,49 @@ // THE SOFTWARE. #include "Animation.h" -#include "Frames.h" -#include "Image.h" -#include "Sprite.h" +#include "../FrameSequence.h" +#include "../Sprite.h" namespace kiwano { Animation::Animation() - : frames_(nullptr) + : frame_seq_(nullptr) { } - Animation::Animation(Duration duration, FramesPtr animation, EaseFunc func) + Animation::Animation(Duration duration, FrameSequencePtr frame_seq, EaseFunc func) : ActionTween(duration, func) - , frames_(nullptr) + , frame_seq_(nullptr) { - this->SetFrames(animation); + this->SetFrameSequence(frame_seq); } Animation::~Animation() { } - FramesPtr Animation::GetFrames() const + FrameSequencePtr Animation::GetFrameSequence() const { - return frames_; + return frame_seq_; } - void Animation::SetFrames(FramesPtr frames) + void Animation::SetFrameSequence(FrameSequencePtr frames) { - frames_ = frames; + frame_seq_ = frames; } void Animation::Init(ActorPtr target) { - if (!frames_ || frames_->GetFrames().empty()) + if (!frame_seq_ || frame_seq_->GetFrames().empty()) { Done(); return; } auto sprite_target = dynamic_cast(target.Get()); - if (sprite_target && frames_) + if (sprite_target && frame_seq_) { - sprite_target->Load(frames_->GetFrames()[0]); + sprite_target->SetFrame(frame_seq_->GetFrames()[0]); } } @@ -72,27 +71,27 @@ namespace kiwano KGE_ASSERT(sprite_target && "Animation only supports Sprites"); - const auto& frames = frames_->GetFrames(); + const auto& frames = frame_seq_->GetFrames(); auto size = frames.size(); auto index = std::min(static_cast(math::Floor(size * percent)), size - 1); - sprite_target->Load(frames[index]); + sprite_target->SetFrame(frames[index]); } ActionPtr Animation::Clone() const { - if (frames_) + if (frame_seq_) { - return new (std::nothrow) Animation(dur_, frames_, ease_func_); + return new (std::nothrow) Animation(dur_, frame_seq_, ease_func_); } return nullptr; } ActionPtr Animation::Reverse() const { - if (frames_) + if (frame_seq_) { - FramesPtr frames = frames_->Reverse(); + FrameSequencePtr frames = frame_seq_->Reverse(); if (frames) { return new (std::nothrow) Animation(dur_, frames, ease_func_); @@ -101,4 +100,4 @@ namespace kiwano return nullptr; } -} \ No newline at end of file +} diff --git a/src/kiwano/2d/Animation.h b/src/kiwano/2d/action/Animation.h similarity index 90% rename from src/kiwano/2d/Animation.h rename to src/kiwano/2d/action/Animation.h index 609761f3..09bab568 100644 --- a/src/kiwano/2d/Animation.h +++ b/src/kiwano/2d/action/Animation.h @@ -32,18 +32,18 @@ namespace kiwano Animation( Duration duration, /* 动画时长 */ - FramesPtr frames, /* 序列帧 */ + FrameSequencePtr frame_seq, /* 序列帧 */ EaseFunc func = nullptr /* 速度变化 */ ); virtual ~Animation(); // 获取动画 - FramesPtr GetFrames() const; + FrameSequencePtr GetFrameSequence() const; // 设置动画 - void SetFrames( - FramesPtr frames + void SetFrameSequence( + FrameSequencePtr frames ); // 获取该动作的拷贝对象 @@ -58,6 +58,6 @@ namespace kiwano void UpdateTween(ActorPtr target, float percent) override; protected: - FramesPtr frames_; + FrameSequencePtr frame_seq_; }; } diff --git a/src/kiwano/2d/include-forwards.h b/src/kiwano/2d/include-forwards.h index 1c0eedad..fb8e6abf 100644 --- a/src/kiwano/2d/include-forwards.h +++ b/src/kiwano/2d/include-forwards.h @@ -34,9 +34,8 @@ namespace kiwano { - KGE_DECLARE_SMART_PTR(Image); - KGE_DECLARE_SMART_PTR(GifImage); - KGE_DECLARE_SMART_PTR(Frames); + KGE_DECLARE_SMART_PTR(Frame); + KGE_DECLARE_SMART_PTR(FrameSequence); KGE_DECLARE_SMART_PTR(Actor); KGE_DECLARE_SMART_PTR(Stage); diff --git a/src/kiwano/base/Resource.cpp b/src/kiwano/base/Resource.cpp index b09b1377..be2387ca 100644 --- a/src/kiwano/base/Resource.cpp +++ b/src/kiwano/base/Resource.cpp @@ -62,7 +62,7 @@ namespace kiwano size_t Resource::GetHashCode() const { if (type_ == Type::File) - return std::hash{}(GetFileName()); + return GetFileName().hash(); return std::hash{}(bin_name_); } @@ -133,4 +133,4 @@ namespace kiwano } return true; } -} \ No newline at end of file +} diff --git a/src/kiwano/kiwano.h b/src/kiwano/kiwano.h index 8a72f512..af336a0a 100644 --- a/src/kiwano/kiwano.h +++ b/src/kiwano/kiwano.h @@ -18,8 +18,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // -// Website: https://www.kiwano.cn -// Source Code: https://github.com/kiwano/kiwano +// Website: https://www.kiwanoengine.com +// Source Code: https://github.com/KiwanoEngine/Kiwano // @@ -60,14 +60,15 @@ // base // +#include "renderer/render.h" +#include "renderer/Image.h" +#include "renderer/GifImage.h" + #include "base/time.h" #include "base/window.h" #include "base/input.h" #include "base/Director.h" #include "base/logs.h" -#include "renderer/render.h" -#include "platform/modules.h" -#include "platform/Application.h" #include "base/Object.h" #include "base/Event.hpp" @@ -83,15 +84,16 @@ #include "2d/Transform.hpp" #include "2d/TextStyle.hpp" -#include "2d/Image.h" -#include "2d/GifImage.h" -#include "2d/Frames.h" -#include "2d/Action.h" -#include "2d/ActionGroup.h" -#include "2d/ActionTween.h" -#include "2d/ActionHelper.h" -#include "2d/Animation.h" -#include "2d/ActionManager.h" +#include "2d/Frame.h" +#include "2d/FrameSequence.h" + +#include "2d/action/Action.h" +#include "2d/action/ActionGroup.h" +#include "2d/action/ActionTween.h" +#include "2d/action/Animation.h" +#include "2d/action/ActionHelper.h" +#include "2d/action/ActionManager.h" + #include "2d/Transition.h" #include "2d/Actor.h" @@ -104,6 +106,8 @@ #include "2d/ShapeNode.h" #include "2d/DebugNode.h" +#include "platform/modules.h" +#include "platform/Application.h" // // utils @@ -112,7 +116,7 @@ #include "utils/Path.h" #include "utils/DataUtil.h" #include "utils/FileUtil.h" -#include "utils/ResLoader.h" +#include "utils/ResourceCache.h" // diff --git a/src/kiwano/math/Vec2.hpp b/src/kiwano/math/Vec2.hpp index acdd8168..1be13ff1 100644 --- a/src/kiwano/math/Vec2.hpp +++ b/src/kiwano/math/Vec2.hpp @@ -33,7 +33,7 @@ namespace kiwano value_type x; value_type y; - Vec2T() : x(0.f), y(0.f) {} + Vec2T() : x(value_type(0)), y(value_type(0)) {} Vec2T(value_type x, value_type y) : x(x), y(y) {} @@ -41,7 +41,7 @@ namespace kiwano inline value_type Length() const { - return math::Sqrt(x * x + y * y); + return static_cast(math::Sqrt(static_cast(x * x + y * y))); } inline bool IsOrigin() const diff --git a/src/kiwano/renderer/D2DDeviceResources.cpp b/src/kiwano/renderer/D2DDeviceResources.cpp index 85833cfe..e72e7222 100644 --- a/src/kiwano/renderer/D2DDeviceResources.cpp +++ b/src/kiwano/renderer/D2DDeviceResources.cpp @@ -19,9 +19,9 @@ // THE SOFTWARE. #include "D2DDeviceResources.h" -#include "../2d/Image.h" +#include "ImageCache.h" #include "../base/logs.h" -#include "../platform/modules.h" +#include "../utils/FileUtil.h" #pragma comment(lib, "d2d1.lib") #pragma comment(lib, "dwrite.lib") @@ -73,9 +73,7 @@ namespace kiwano ID2D1StrokeStyle* GetStrokeStyle(StrokeStyle stroke) const override; - void ClearImageCache() override; - - void DiscardResources() override; + void DiscardResources() override; public: unsigned long STDMETHODCALLTYPE AddRef(); @@ -91,9 +89,6 @@ namespace kiwano unsigned long ref_count_; float dpi_; - using BitmapMap = UnorderedMap>; - BitmapMap bitmap_cache_; - ComPtr d2d_miter_stroke_style_; ComPtr d2d_bevel_stroke_style_; ComPtr d2d_round_stroke_style_; @@ -179,7 +174,7 @@ namespace kiwano void D2DDeviceResources::DiscardResources() { - ClearImageCache(); + ImageCache::Instance()->Clear(); factory_.Reset(); device_.Reset(); @@ -328,11 +323,10 @@ namespace kiwano if (!imaging_factory_ || !device_context_) return E_UNEXPECTED; - size_t hash_code = std::hash{}(file_path); - if (bitmap_cache_.find(hash_code) != bitmap_cache_.end()) + if (!FileUtil::ExistsFile(file_path)) { - bitmap = bitmap_cache_[hash_code]; - return S_OK; + KGE_WARNING_LOG(L"Image file '%s' not found!", file_path.c_str()); + return E_FAIL; } ComPtr decoder; @@ -384,9 +378,7 @@ namespace kiwano if (SUCCEEDED(hr)) { bitmap = bitmap_tmp; - bitmap_cache_.insert(std::make_pair(hash_code, bitmap)); } - return hr; } @@ -395,13 +387,6 @@ namespace kiwano if (!imaging_factory_ || !device_context_) return E_UNEXPECTED; - size_t hash_code = res.GetHashCode(); - if (bitmap_cache_.find(hash_code) != bitmap_cache_.end()) - { - bitmap = bitmap_cache_[hash_code]; - return S_OK; - } - ComPtr decoder; ComPtr source; ComPtr stream; @@ -471,9 +456,7 @@ namespace kiwano if (SUCCEEDED(hr)) { bitmap = bitmap_tmp; - bitmap_cache_.insert(std::make_pair(hash_code, bitmap)); } - return hr; } @@ -599,11 +582,6 @@ namespace kiwano return hr; } - void D2DDeviceResources::ClearImageCache() - { - bitmap_cache_.clear(); - } - ID2D1StrokeStyle* D2DDeviceResources::GetStrokeStyle(StrokeStyle stroke) const { switch (stroke) @@ -615,4 +593,4 @@ namespace kiwano return nullptr; } -} \ No newline at end of file +} diff --git a/src/kiwano/renderer/D2DDeviceResources.h b/src/kiwano/renderer/D2DDeviceResources.h index 18e785a3..c9de4e4c 100644 --- a/src/kiwano/renderer/D2DDeviceResources.h +++ b/src/kiwano/renderer/D2DDeviceResources.h @@ -70,8 +70,6 @@ namespace kiwano _In_ ComPtr const& target ) = 0; - virtual void ClearImageCache() = 0; - virtual void DiscardResources() = 0; inline ID2D1Factory1* GetFactory() const { KGE_ASSERT(factory_); return factory_.Get(); } diff --git a/src/kiwano/renderer/D3D10DeviceResources.cpp b/src/kiwano/renderer/D3D10DeviceResources.cpp index 3d65fead..75123756 100644 --- a/src/kiwano/renderer/D3D10DeviceResources.cpp +++ b/src/kiwano/renderer/D3D10DeviceResources.cpp @@ -20,7 +20,6 @@ #include "D3D10DeviceResources.h" -#include "../2d/Image.h" #include "../base/logs.h" #pragma comment(lib, "d3d10_1.lib") diff --git a/src/kiwano/renderer/D3D11DeviceResources.cpp b/src/kiwano/renderer/D3D11DeviceResources.cpp index 338095db..42c07f01 100644 --- a/src/kiwano/renderer/D3D11DeviceResources.cpp +++ b/src/kiwano/renderer/D3D11DeviceResources.cpp @@ -20,7 +20,6 @@ #include "D3D11DeviceResources.h" -#include "../2d/Image.h" #include "../base/logs.h" #include // IsWindows10OrGreater diff --git a/src/kiwano/2d/GifImage.cpp b/src/kiwano/renderer/GifImage.cpp similarity index 99% rename from src/kiwano/2d/GifImage.cpp rename to src/kiwano/renderer/GifImage.cpp index a099eb70..a2f1278a 100644 --- a/src/kiwano/2d/GifImage.cpp +++ b/src/kiwano/renderer/GifImage.cpp @@ -20,7 +20,6 @@ #include "GifImage.h" #include "../base/logs.h" -#include "../platform/modules.h" #include "../utils/FileUtil.h" namespace kiwano diff --git a/src/kiwano/2d/GifImage.h b/src/kiwano/renderer/GifImage.h similarity index 97% rename from src/kiwano/2d/GifImage.h rename to src/kiwano/renderer/GifImage.h index d105559d..6e7d5c0c 100644 --- a/src/kiwano/2d/GifImage.h +++ b/src/kiwano/renderer/GifImage.h @@ -19,12 +19,13 @@ // THE SOFTWARE. #pragma once -#include "include-forwards.h" #include "../base/Resource.h" -#include "../renderer/render.h" +#include "render.h" namespace kiwano { + // GIF 图像 + KGE_DECLARE_SMART_PTR(GifImage); class KGE_API GifImage : public Object { diff --git a/src/kiwano/renderer/Image.cpp b/src/kiwano/renderer/Image.cpp new file mode 100644 index 00000000..d1189c14 --- /dev/null +++ b/src/kiwano/renderer/Image.cpp @@ -0,0 +1,113 @@ +// 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 "Image.h" +#include "../base/logs.h" +#include "../platform/modules.h" + +namespace kiwano +{ + Image::Image() + : bitmap_(nullptr) + { + } + + Image::Image(ComPtr const & bitmap) + : Image() + { + SetBitmap(bitmap); + } + + Image::~Image() + { + } + + bool Image::IsValid() const + { + return !!bitmap_; + } + + float Image::GetWidth() const + { + if (bitmap_) + { + return bitmap_->GetSize().width; + } + return 0; + } + + float Image::GetHeight() const + { + if (bitmap_) + { + return bitmap_->GetSize().height; + } + return 0; + } + + Size Image::GetSize() const + { + if (bitmap_) + { + auto bitmap_size = bitmap_->GetSize(); + return Size{ bitmap_size.width, bitmap_size.height }; + } + return Size{}; + } + + UINT32 Image::GetWidthInPixels() const + { + if (bitmap_) + { + return bitmap_->GetPixelSize().width; + } + return 0; + } + + UINT32 Image::GetHeightInPixels() const + { + if (bitmap_) + { + return bitmap_->GetPixelSize().height; + } + return 0; + } + + math::Vec2T Image::GetSizeInPixels() const + { + if (bitmap_) + { + auto bitmap_size = bitmap_->GetPixelSize(); + return math::Vec2T{ bitmap_size.width, bitmap_size.height }; + } + return math::Vec2T{}; + } + + ComPtr Image::GetBitmap() const + { + return bitmap_; + } + + void Image::SetBitmap(ComPtr bitmap) + { + bitmap_ = bitmap; + } + +} diff --git a/src/kiwano/2d/Image.h b/src/kiwano/renderer/Image.h similarity index 63% rename from src/kiwano/2d/Image.h rename to src/kiwano/renderer/Image.h index 3659e0de..c3d6ee89 100644 --- a/src/kiwano/2d/Image.h +++ b/src/kiwano/renderer/Image.h @@ -19,86 +19,53 @@ // THE SOFTWARE. #pragma once -#include "include-forwards.h" #include "../base/Resource.h" -#include "../renderer/render.h" +#include "render.h" // ID2D1Bitmap namespace kiwano { - // 图片 + // 图像 + KGE_DECLARE_SMART_PTR(Image); class KGE_API Image : public Object { public: Image(); - explicit Image( - Resource const& res - ); - - explicit Image( - Resource const& res, - Rect const& crop_rect /* 裁剪矩形 */ - ); - explicit Image( ComPtr const& bitmap ); virtual ~Image(); - // 加载图片资源 - bool Load( - Resource const& res - ); - // 资源是否有效 bool IsValid() const; - // 将图片裁剪为矩形 - void Crop( - Rect const& crop_rect /* 裁剪矩形 */ - ); - - // 获取宽度 + // 获取位图宽度 float GetWidth() const; - // 获取高度 + // 获取位图高度 float GetHeight() const; - // 获取大小 + // 获取位图大小 Size GetSize() const; - // 获取源图片宽度 - float GetSourceWidth() const; + // 获取位图像素宽度 + UINT32 GetWidthInPixels() const; - // 获取源图片高度 - float GetSourceHeight() const; + // 获取位图像素高度 + UINT32 GetHeightInPixels() const; - // 获取源图片大小 - Size GetSourceSize() const; + // 获取位图像素大小 + math::Vec2T GetSizeInPixels() const; - // 获取裁剪位置 X 坐标 - float GetCropX() const; + // 获取源位图 + ComPtr GetBitmap() const; - // 获取裁剪位置 Y 坐标 - float GetCropY() const; - - // 获取裁剪位置 - Point GetCropPos() const; - - // 获取裁剪矩形 - Rect GetCropRect() const; - - ComPtr const& GetBitmap() const; + // 设置源位图 + void SetBitmap(ComPtr bitmap); protected: - void SetBitmap( - ComPtr const& bitmap - ); - - protected: - Rect crop_rect_; ComPtr bitmap_; }; } diff --git a/src/kiwano/renderer/ImageCache.cpp b/src/kiwano/renderer/ImageCache.cpp new file mode 100644 index 00000000..7079e466 --- /dev/null +++ b/src/kiwano/renderer/ImageCache.cpp @@ -0,0 +1,83 @@ +// Copyright (c) 2016-2019 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 "ImageCache.h" +#include "../base/logs.h" + +namespace kiwano +{ + + ImageCache::ImageCache() + { + } + + ImageCache::~ImageCache() + { + } + + ImagePtr ImageCache::AddImage(Resource const& res) + { + size_t hash_code = res.GetHashCode(); + auto iter = image_cache_.find(hash_code); + if (iter != image_cache_.end()) + { + return iter->second; + } + + HRESULT hr = S_OK; + ComPtr bitmap; + + if (res.IsFileType()) + { + hr = Renderer::Instance()->GetD2DDeviceResources()->CreateBitmapFromFile(bitmap, res.GetFileName()); + } + else + { + hr = Renderer::Instance()->GetD2DDeviceResources()->CreateBitmapFromResource(bitmap, res); + } + + if (SUCCEEDED(hr)) + { + ImagePtr ptr = new Image(bitmap); + image_cache_.insert(std::make_pair(hash_code, ptr)); + } + else + { + KGE_ERROR_LOG(L"Load image file failed with HRESULT of %08X", hr); + } + return nullptr; + } + + void ImageCache::RemoveImage(Resource const& res) + { + size_t hash_code = res.GetHashCode(); + auto iter = image_cache_.find(hash_code); + if (iter != image_cache_.end()) + { + image_cache_.erase(iter); + } + } + + void ImageCache::Clear() + { + image_cache_.clear(); + } + +} diff --git a/src/kiwano/renderer/ImageCache.h b/src/kiwano/renderer/ImageCache.h new file mode 100644 index 00000000..fb565790 --- /dev/null +++ b/src/kiwano/renderer/ImageCache.h @@ -0,0 +1,48 @@ +// Copyright (c) 2016-2019 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. + +#pragma once +#include "../common/Singleton.hpp" +#include "render.h" + +namespace kiwano +{ + class KGE_API ImageCache + : public Singleton + { + KGE_DECLARE_SINGLETON(ImageCache); + + public: + ImagePtr AddImage(Resource const& res); + + void RemoveImage(Resource const& res); + + void Clear(); + + protected: + ImageCache(); + + virtual ~ImageCache(); + + protected: + using ImageMap = UnorderedMap; + ImageMap image_cache_; + }; +} diff --git a/src/kiwano/renderer/render.cpp b/src/kiwano/renderer/render.cpp index 1354071d..94fc2262 100644 --- a/src/kiwano/renderer/render.cpp +++ b/src/kiwano/renderer/render.cpp @@ -19,7 +19,6 @@ // THE SOFTWARE. #include "render.h" -#include "../2d/Image.h" #include "../base/logs.h" #include "../base/window.h" @@ -29,7 +28,7 @@ namespace kiwano : hwnd_(nullptr) , antialias_(true) , vsync_(true) - , text_antialias_(TextAntialias::ClearType) + , text_antialias_(TextAntialias::GrayScale) , clear_color_(Color::Black) , opacity_(1.f) , collecting_status_(false) @@ -292,27 +291,6 @@ namespace kiwano return S_OK; } - HRESULT Renderer::DrawImage(ImagePtr image, Rect const& dest_rect) - { - if (!device_context_) - return E_UNEXPECTED; - - if (!image->GetBitmap()) - return S_OK; - - device_context_->DrawBitmap( - image->GetBitmap().Get(), - DX::ConvertToRectF(dest_rect), - opacity_, - D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, - DX::ConvertToRectF(image->GetCropRect()) - ); - - if (collecting_status_) - ++status_.primitives; - return S_OK; - } - HRESULT Renderer::DrawBitmap(ComPtr const & bitmap, Rect const& src_rect, Rect const& dest_rect) { if (!device_context_) @@ -321,7 +299,6 @@ namespace kiwano if (!bitmap) return S_OK; - // Do not crop bitmap device_context_->DrawBitmap( bitmap.Get(), DX::ConvertToRectF(dest_rect), diff --git a/src/kiwano/renderer/render.h b/src/kiwano/renderer/render.h index 2c03a701..d71510ec 100644 --- a/src/kiwano/renderer/render.h +++ b/src/kiwano/renderer/render.h @@ -26,6 +26,7 @@ #include "../2d/Font.hpp" #include "../2d/TextStyle.hpp" #include "helper.hpp" +#include "Image.h" #include "TextRenderer.h" #include "D2DDeviceResources.h" @@ -79,11 +80,6 @@ namespace kiwano Color const& fill_color ); - HRESULT DrawImage( - ImagePtr image, - Rect const& dest_rect - ); - HRESULT DrawBitmap( ComPtr const& bitmap, Rect const& src_rect, diff --git a/src/kiwano/utils/ResLoader.cpp b/src/kiwano/utils/ResourceCache.cpp similarity index 64% rename from src/kiwano/utils/ResLoader.cpp rename to src/kiwano/utils/ResourceCache.cpp index 17fe4b4a..ae551868 100644 --- a/src/kiwano/utils/ResLoader.cpp +++ b/src/kiwano/utils/ResourceCache.cpp @@ -18,11 +18,11 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include "ResLoader.h" +#include "ResourceCache.h" #include "../base/logs.h" -#include "../2d/Image.h" -#include "../2d/Frames.h" -#include "../2d/GifImage.h" +#include "../2d/Frame.h" +#include "../2d/FrameSequence.h" +#include "../renderer/GifImage.h" #include "FileUtil.h" #include @@ -35,7 +35,7 @@ namespace kiwano String path; }; - bool LoadImagesFromData(ResLoader* loader, GlobalData* gdata, const String* id, const String* type, + bool LoadImagesFromData(ResourceCache* loader, GlobalData* gdata, const String* id, const String* type, const String* file, const Array* files, int rows, int cols) { if (!gdata || !id) return false; @@ -52,13 +52,13 @@ namespace kiwano { if (rows || cols) { - // Image slices - return !!loader->AddFrames(*id, Resource(gdata->path + (*file)), std::max(cols, 1), std::max(rows, 1)); + // Frame slices + return !!loader->AddFrameSequence(*id, Resource(gdata->path + (*file)), std::max(cols, 1), std::max(rows, 1)); } else { // Simple image - return loader->AddImage(*id, Resource(gdata->path + (*file))); + return loader->AddFrame(*id, Resource(gdata->path + (*file))); } } } @@ -66,22 +66,22 @@ namespace kiwano // Frames if (files) { - Array images; - images.reserve(files->size()); + Array frames; + frames.reserve(files->size()); for (const auto& file : (*files)) { - ImagePtr image = new Image(gdata->path + (file)); - if (image->IsValid()) + FramePtr frame = new Frame; + if (frame->Load(gdata->path + (file))) { - images.push_back(image); + frames.push_back(frame); } } - return !!loader->AddFrames(*id, images); + return !!loader->AddFrameSequence(*id, frames); } return false; } - bool LoadJsonData(ResLoader* loader, Json const& json_data) + bool LoadJsonData(ResourceCache* loader, Json const& json_data) { GlobalData global_data; if (json_data.count(L"path")) @@ -123,7 +123,7 @@ namespace kiwano return true; } - bool LoadXmlData(ResLoader* loader, tinyxml2::XMLElement* elem) + bool LoadXmlData(ResourceCache* loader, tinyxml2::XMLElement* elem) { GlobalData global_data; if (auto path = elem->FirstChildElement(L"path")) @@ -170,18 +170,18 @@ namespace kiwano namespace { - Map> load_json_funcs = { + Map> load_json_funcs = { { L"latest", __res_loader_01::LoadJsonData }, { L"0.1", __res_loader_01::LoadJsonData }, }; - Map> load_xml_funcs = { + Map> load_xml_funcs = { { L"latest", __res_loader_01::LoadXmlData }, { L"0.1", __res_loader_01::LoadXmlData }, }; } - bool ResLoader::LoadFromJsonFile(String const& file_path) + bool ResourceCache::LoadFromJsonFile(String const& file_path) { Json json_data; std::wifstream ifs; @@ -195,18 +195,18 @@ namespace kiwano } catch (std::wifstream::failure& e) { - KGE_WARNING_LOG(L"ResLoader::LoadFromJsonFile failed: Cannot open file. (%s)", string_to_wide(e.what()).c_str()); + KGE_WARNING_LOG(L"ResourceCache::LoadFromJsonFile failed: Cannot open file. (%s)", string_to_wide(e.what()).c_str()); return false; } catch (json_exception& e) { - KGE_WARNING_LOG(L"ResLoader::LoadFromJsonFile failed: Cannot parse to JSON. (%s)", string_to_wide(e.what()).c_str()); + KGE_WARNING_LOG(L"ResourceCache::LoadFromJsonFile failed: Cannot parse to JSON. (%s)", string_to_wide(e.what()).c_str()); return false; } return LoadFromJson(json_data); } - bool ResLoader::LoadFromJson(Json const& json_data) + bool ResourceCache::LoadFromJson(Json const& json_data) { try { @@ -228,13 +228,13 @@ namespace kiwano } catch (std::exception& e) { - KGE_WARNING_LOG(L"ResLoader::LoadFromJson failed: JSON data is invalid. (%s)", string_to_wide(e.what()).c_str()); + KGE_WARNING_LOG(L"ResourceCache::LoadFromJson failed: JSON data is invalid. (%s)", string_to_wide(e.what()).c_str()); return false; } return false; } - bool ResLoader::LoadFromXmlFile(String const& file_path) + bool ResourceCache::LoadFromXmlFile(String const& file_path) { tinyxml2::XMLDocument doc; @@ -250,21 +250,21 @@ namespace kiwano if (tinyxml2::XML_SUCCESS != doc.Parse(ss.str().c_str())) { - KGE_WARNING_LOG(L"ResLoader::LoadFromXmlFile failed: %s (%s)", + KGE_WARNING_LOG(L"ResourceCache::LoadFromXmlFile failed: %s (%s)", tinyxml2::XMLDocument::ErrorIDToName(doc.ErrorID()), doc.ErrorStr()); return false; } } catch (std::wifstream::failure& e) { - KGE_WARNING_LOG(L"ResLoader::LoadFromXmlFile failed: Cannot open file. (%s)", string_to_wide(e.what()).c_str()); + KGE_WARNING_LOG(L"ResourceCache::LoadFromXmlFile failed: Cannot open file. (%s)", string_to_wide(e.what()).c_str()); return false; } return LoadFromXml(&doc); } - bool ResLoader::LoadFromXml(tinyxml2::XMLDocument* doc) + bool ResourceCache::LoadFromXml(tinyxml2::XMLDocument* doc) { if (doc) { @@ -292,42 +292,42 @@ namespace kiwano } catch (std::exception& e) { - KGE_WARNING_LOG(L"ResLoader::LoadFromXml failed: %s", string_to_wide(e.what()).c_str()); + KGE_WARNING_LOG(L"ResourceCache::LoadFromXml failed: %s", string_to_wide(e.what()).c_str()); return false; } } return false; } - bool ResLoader::AddImage(String const& id, Resource const& image) + bool ResourceCache::AddFrame(String const& id, Resource const& res) { - ImagePtr ptr = new (std::nothrow) Image; + FramePtr ptr = new (std::nothrow) Frame; if (ptr) { - if (ptr->Load(image)) + if (ptr->Load(res)) { - return AddImage(id, ptr); + return AddFrame(id, ptr); } } return false; } - bool ResLoader::AddImage(String const & id, ImagePtr image) + bool ResourceCache::AddFrame(String const & id, FramePtr frame) { - if (image) + if (frame) { - res_.insert(std::make_pair(id, image)); + cache_.insert(std::make_pair(id, frame)); return true; } return false; } - bool ResLoader::AddGifImage(String const& id, Resource const& image) + bool ResourceCache::AddGifImage(String const& id, Resource const& res) { GifImagePtr ptr = new (std::nothrow) GifImage; if (ptr) { - if (ptr->Load(image)) + if (ptr->Load(res)) { return AddGifImage(id, ptr); } @@ -335,27 +335,27 @@ namespace kiwano return false; } - bool ResLoader::AddGifImage(String const& id, GifImagePtr image) + bool ResourceCache::AddGifImage(String const& id, GifImagePtr image) { if (image) { - res_.insert(std::make_pair(id, image)); + cache_.insert(std::make_pair(id, image)); return true; } return false; } - size_t ResLoader::AddFrames(String const& id, Array const& images) + size_t ResourceCache::AddFrameSequence(String const& id, Array const& images) { if (images.empty()) return 0; - Array image_arr; + Array image_arr; image_arr.reserve(images.size()); for (const auto& image : images) { - ImagePtr ptr = new (std::nothrow) Image; + FramePtr ptr = new (std::nothrow) Frame; if (ptr) { if (ptr->Load(image)) @@ -367,43 +367,43 @@ namespace kiwano if (!image_arr.empty()) { - FramesPtr frames = new (std::nothrow) Frames(image_arr); - return AddFrames(id, frames); + FrameSequencePtr frames = new (std::nothrow) FrameSequence(image_arr); + return AddFrameSequence(id, frames); } return 0; } - size_t ResLoader::AddFrames(String const& id, Array const& images) + size_t ResourceCache::AddFrameSequence(String const& id, Array const& images) { if (images.empty()) return 0; - FramesPtr frames = new (std::nothrow) Frames(images); - return AddFrames(id, frames); + FrameSequencePtr frames = new (std::nothrow) FrameSequence(images); + return AddFrameSequence(id, frames); } - size_t ResLoader::AddFrames(String const & id, Resource const & image, int cols, int rows) + size_t ResourceCache::AddFrameSequence(String const & id, Resource const & image, int cols, int rows) { if (cols <= 0 || rows <= 0) return 0; - ImagePtr raw = new (std::nothrow) Image; + FramePtr raw = new (std::nothrow) Frame; if (!raw || !raw->Load(image)) return false; - float raw_width = raw->GetSourceWidth(); - float raw_height = raw->GetSourceHeight(); + float raw_width = raw->GetWidth(); + float raw_height = raw->GetHeight(); float width = raw_width / cols; float height = raw_height / rows; - Array image_arr; + Array image_arr; image_arr.reserve(rows * cols); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { - ImagePtr ptr = new (std::nothrow) Image(raw->GetBitmap()); + FramePtr ptr = new (std::nothrow) Frame(raw->GetImage()); if (ptr) { ptr->Crop(Rect{ j * width, i * height, width, height }); @@ -412,22 +412,22 @@ namespace kiwano } } - FramesPtr frames = new (std::nothrow) Frames(image_arr); - return AddFrames(id, frames); + FrameSequencePtr frames = new (std::nothrow) FrameSequence(image_arr); + return AddFrameSequence(id, frames); } - size_t ResLoader::AddFrames(String const & id, Resource const & image, Array const & crop_rects) + size_t ResourceCache::AddFrameSequence(String const & id, Resource const & image, Array const & crop_rects) { - ImagePtr raw = new (std::nothrow) Image; + FramePtr raw = new (std::nothrow) Frame; if (!raw || !raw->Load(image)) return 0; - Array image_arr; + Array image_arr; image_arr.reserve(crop_rects.size()); for (const auto& rect : crop_rects) { - ImagePtr ptr = new (std::nothrow) Image(raw->GetBitmap()); + FramePtr ptr = new (std::nothrow) Frame(raw->GetImage()); if (ptr) { ptr->Crop(rect); @@ -435,62 +435,62 @@ namespace kiwano } } - FramesPtr frames = new (std::nothrow) Frames(image_arr); - return AddFrames(id, frames); + FrameSequencePtr frames = new (std::nothrow) FrameSequence(image_arr); + return AddFrameSequence(id, frames); } - size_t ResLoader::AddFrames(String const & id, FramesPtr frames) + size_t ResourceCache::AddFrameSequence(String const & id, FrameSequencePtr frames) { if (frames) { - res_.insert(std::make_pair(id, frames)); + cache_.insert(std::make_pair(id, frames)); return frames->GetFrames().size(); } return 0; } - bool ResLoader::AddObj(String const& id, ObjectPtr obj) + bool ResourceCache::AddObj(String const& id, ObjectPtr obj) { if (obj) { - res_.insert(std::make_pair(id, obj)); + cache_.insert(std::make_pair(id, obj)); return true; } return false; } - ImagePtr ResLoader::GetImage(String const & id) const + FramePtr ResourceCache::GetFrame(String const & id) const { - return Get(id); + return Get(id); } - GifImagePtr ResLoader::GetGifImage(String const& id) const + GifImagePtr ResourceCache::GetGifImage(String const& id) const { return Get(id); } - FramesPtr ResLoader::GetFrames(String const & id) const + FrameSequencePtr ResourceCache::GetFrameSequence(String const & id) const { - return Get(id); + return Get(id); } - void ResLoader::Delete(String const & id) + void ResourceCache::Delete(String const & id) { - res_.erase(id); + cache_.erase(id); } - void ResLoader::Destroy() + void ResourceCache::Destroy() { - res_.clear(); + cache_.clear(); } - ResLoader::ResLoader() + ResourceCache::ResourceCache() { } - ResLoader::~ResLoader() + ResourceCache::~ResourceCache() { Destroy(); } -} \ No newline at end of file +} diff --git a/src/kiwano/utils/ResLoader.h b/src/kiwano/utils/ResourceCache.h similarity index 69% rename from src/kiwano/utils/ResLoader.h rename to src/kiwano/utils/ResourceCache.h index 8ca75c55..0fca758d 100644 --- a/src/kiwano/utils/ResLoader.h +++ b/src/kiwano/utils/ResourceCache.h @@ -24,12 +24,13 @@ #include "../common/Json.hpp" #include "../base/Resource.h" #include "../2d/include-forwards.h" +#include "../renderer/GifImage.h" #include "../third-party/tinyxml2/tinyxml2.h" namespace kiwano { - // 资源加载器 - class KGE_API ResLoader + // 资源缓存 + class KGE_API ResourceCache { public: // 从 JSON 文件加载资源信息 @@ -45,45 +46,45 @@ namespace kiwano bool LoadFromXml(tinyxml2::XMLDocument* doc); // 添加图片 - bool AddImage(String const& id, Resource const& image); + bool AddFrame(String const& id, Resource const& res); // 添加图片 - bool AddImage(String const& id, ImagePtr image); + bool AddFrame(String const& id, FramePtr frame); // 添加 GIF 图片 - bool AddGifImage(String const& id, Resource const& image); + bool AddGifImage(String const& id, Resource const& res); // 添加 GIF 图片 bool AddGifImage(String const& id, GifImagePtr image); - // 添加帧集合 - size_t AddFrames(String const& id, Array const& images); + // 添加序列帧 + size_t AddFrameSequence(String const& id, Array const& frames); - // 添加帧集合 - size_t AddFrames(String const& id, Array const& images); + // 添加序列帧 + size_t AddFrameSequence(String const& id, Array const& frames); - // 添加帧集合 + // 添加序列帧 // 按行列数裁剪图片 - size_t AddFrames(String const& id, Resource const& image, int cols, int rows = 1); + size_t AddFrameSequence(String const& id, Resource const& frame, int cols, int rows = 1); - // 添加帧集合 + // 添加序列帧 // 按指定裁剪矩形裁剪图片 - size_t AddFrames(String const& id, Resource const& image, Array const& crop_rects); + size_t AddFrameSequence(String const& id, Resource const& frame, Array const& crop_rects); - // 添加帧集合 - size_t AddFrames(String const& id, FramesPtr frames); + // 添加序列帧 + size_t AddFrameSequence(String const& id, FrameSequencePtr frames); // 添加对象 bool AddObj(String const& id, ObjectPtr obj); // 获取图片资源 - ImagePtr GetImage(String const& id) const; + FramePtr GetFrame(String const& id) const; // 获取 GIF 图片资源 GifImagePtr GetGifImage(String const& id) const; // 获取序列帧 - FramesPtr GetFrames(String const& id) const; + FrameSequencePtr GetFrameSequence(String const& id) const; // 删除指定资源 void Delete(String const& id); @@ -94,18 +95,18 @@ namespace kiwano template _Ty* Get(String const& id) const { - auto iter = res_.find(id); - if (iter == res_.end()) + auto iter = cache_.find(id); + if (iter == cache_.end()) return nullptr; return dynamic_cast<_Ty*>((*iter).second.Get()); } public: - ResLoader(); + ResourceCache(); - virtual ~ResLoader(); + virtual ~ResourceCache(); protected: - UnorderedMap res_; + UnorderedMap cache_; }; } From 222b09f1662ceb5e8df6a8649b9d0a9b20911a1c Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Tue, 13 Aug 2019 15:00:43 +0800 Subject: [PATCH 02/11] Refactor Singleton && Singleton mode ResourceCache --- src/kiwano-audio/src/Sound.cpp | 2 +- src/kiwano-imgui/src/ImGuiModule.cpp | 18 +- src/kiwano/2d/Actor.cpp | 4 +- src/kiwano/2d/Canvas.cpp | 14 +- src/kiwano/2d/DebugNode.cpp | 6 +- src/kiwano/2d/Frame.cpp | 2 +- src/kiwano/2d/GifSprite.cpp | 4 +- src/kiwano/2d/Layer.cpp | 2 +- src/kiwano/2d/ShapeNode.cpp | 16 +- src/kiwano/2d/Sprite.cpp | 2 +- src/kiwano/2d/Stage.cpp | 2 +- src/kiwano/2d/Text.cpp | 4 +- src/kiwano/2d/Transition.cpp | 8 +- src/kiwano/2d/action/ActionTween.cpp | 2 +- src/kiwano/base/logs.h | 8 +- src/kiwano/common/Singleton.hpp | 15 +- src/kiwano/platform/Application.cpp | 38 +-- src/kiwano/renderer/D2DDeviceResources.cpp | 2 +- src/kiwano/renderer/GifImage.cpp | 8 +- src/kiwano/renderer/ImageCache.cpp | 4 +- src/kiwano/renderer/render.cpp | 4 +- src/kiwano/ui/Button.cpp | 4 +- src/kiwano/utils/ResourceCache.cpp | 312 +++++++++++---------- src/kiwano/utils/ResourceCache.h | 10 +- 24 files changed, 254 insertions(+), 237 deletions(-) diff --git a/src/kiwano-audio/src/Sound.cpp b/src/kiwano-audio/src/Sound.cpp index 653f7f7d..12201b09 100644 --- a/src/kiwano-audio/src/Sound.cpp +++ b/src/kiwano-audio/src/Sound.cpp @@ -81,7 +81,7 @@ namespace kiwano return false; } - hr = Audio::Instance()->CreateVoice(&voice_, transcoder.GetWaveFormatEx()); + hr = Audio::GetInstance()->CreateVoice(&voice_, transcoder.GetWaveFormatEx()); if (FAILED(hr)) { if (wave_data_) diff --git a/src/kiwano-imgui/src/ImGuiModule.cpp b/src/kiwano-imgui/src/ImGuiModule.cpp index a0ca02e1..da5f8baa 100644 --- a/src/kiwano-imgui/src/ImGuiModule.cpp +++ b/src/kiwano-imgui/src/ImGuiModule.cpp @@ -45,9 +45,9 @@ namespace kiwano //ImGui::StyleColorsClassic(); // Setup Platform/Renderer bindings - Init(Window::Instance()->GetHandle()); + Init(Window::GetInstance()->GetHandle()); - target_window_ = Renderer::Instance()->GetTargetWindow(); + target_window_ = Renderer::GetInstance()->GetTargetWindow(); } void ImGuiModule::DestroyComponent() @@ -64,9 +64,9 @@ namespace kiwano io.DeltaTime = dt.Seconds(); // Read keyboard modifiers inputs - io.KeyCtrl = Input::Instance()->IsDown(KeyCode::Ctrl); - io.KeyShift = Input::Instance()->IsDown(KeyCode::Shift); - io.KeyAlt = Input::Instance()->IsDown(KeyCode::Alt); + io.KeyCtrl = Input::GetInstance()->IsDown(KeyCode::Ctrl); + io.KeyShift = Input::GetInstance()->IsDown(KeyCode::Shift); + io.KeyAlt = Input::GetInstance()->IsDown(KeyCode::Alt); io.KeySuper = false; // io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below. @@ -106,7 +106,7 @@ namespace kiwano io.KeyMap[ImGuiKey_Y] = KeyCode::Y; io.KeyMap[ImGuiKey_Z] = KeyCode::Z; - ImGui_Impl_Init(Renderer::Instance()); + ImGui_Impl_Init(Renderer::GetInstance()); } void ImGuiModule::BeforeRender() @@ -213,7 +213,7 @@ namespace kiwano KGE_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built!"); // Setup display size (every frame to accommodate for window resizing) - Size display_size = Renderer::Instance()->GetOutputSize(); + Size display_size = Renderer::GetInstance()->GetOutputSize(); io.DisplaySize = ImVec2(display_size.x, display_size.y); ImGui::NewFrame(); @@ -238,7 +238,7 @@ namespace kiwano ::SetCursorPos(pos.x, pos.y); } - Point pos = Input::Instance()->GetMousePos(); + Point pos = Input::GetInstance()->GetMousePos(); io.MousePos = ImVec2(pos.x, pos.y); } @@ -260,7 +260,7 @@ namespace kiwano case ImGuiMouseCursor_Hand: cursor = MouseCursor::Hand; break; } - Window::Instance()->SetMouseCursor(cursor); + Window::GetInstance()->SetMouseCursor(cursor); } void ImGuiModule::UpdateGamepads() { diff --git a/src/kiwano/2d/Actor.cpp b/src/kiwano/2d/Actor.cpp index a44868c4..485321a3 100644 --- a/src/kiwano/2d/Actor.cpp +++ b/src/kiwano/2d/Actor.cpp @@ -124,7 +124,7 @@ namespace kiwano { Rect bounds = GetBounds(); - auto renderer = Renderer::Instance(); + auto renderer = Renderer::GetInstance(); renderer->SetTransform(transform_matrix_); renderer->FillRectangle(bounds, Color(Color::Red, .4f)); renderer->DrawRectangle(bounds, Color(Color::Red, .8f), 4.f); @@ -659,7 +659,7 @@ namespace kiwano void VisualActor::PrepareRender() { - auto renderer = Renderer::Instance(); + auto renderer = Renderer::GetInstance(); renderer->SetTransform(transform_matrix_); renderer->SetOpacity(displayed_opacity_); } diff --git a/src/kiwano/2d/Canvas.cpp b/src/kiwano/2d/Canvas.cpp index ebb6032b..d1e652f5 100644 --- a/src/kiwano/2d/Canvas.cpp +++ b/src/kiwano/2d/Canvas.cpp @@ -28,7 +28,7 @@ namespace kiwano : cache_expired_(false) , stroke_width_(1.0f) { - auto ctx = Renderer::Instance()->GetD2DDeviceResources()->GetDeviceContext(); + auto ctx = Renderer::GetInstance()->GetD2DDeviceResources()->GetDeviceContext(); ThrowIfFailed( ctx->CreateCompatibleRenderTarget(&render_target_) @@ -96,7 +96,7 @@ namespace kiwano if (bitmap_cached_) { Rect bitmap_rect(0.f, 0.f, bitmap_cached_->GetSize().width, bitmap_cached_->GetSize().height); - Renderer::Instance()->DrawBitmap( + Renderer::GetInstance()->DrawBitmap( bitmap_cached_, bitmap_rect, bitmap_rect @@ -121,7 +121,7 @@ namespace kiwano void Canvas::SetOutlineJoinStyle(StrokeStyle outline_join) { - outline_join_style_ = Renderer::Instance()->GetD2DDeviceResources()->GetStrokeStyle(outline_join); + outline_join_style_ = Renderer::GetInstance()->GetD2DDeviceResources()->GetStrokeStyle(outline_join); } void Canvas::SetTextStyle(Font const& font, TextStyle const & text_style) @@ -135,7 +135,7 @@ namespace kiwano text_style_.outline, DX::ConvertToColorF(text_style_.outline_color), text_style_.outline_width, - Renderer::Instance()->GetD2DDeviceResources()->GetStrokeStyle(text_style_.outline_stroke) + Renderer::GetInstance()->GetD2DDeviceResources()->GetStrokeStyle(text_style_.outline_stroke) ); // clear text format @@ -271,7 +271,7 @@ namespace kiwano if (!text_format_) { ThrowIfFailed( - Renderer::Instance()->GetD2DDeviceResources()->CreateTextFormat( + Renderer::GetInstance()->GetD2DDeviceResources()->CreateTextFormat( text_format_, text_font_, text_style_ @@ -282,7 +282,7 @@ namespace kiwano ComPtr text_layout; Size layout_size; ThrowIfFailed( - Renderer::Instance()->GetD2DDeviceResources()->CreateTextLayout( + Renderer::GetInstance()->GetD2DDeviceResources()->CreateTextLayout( text_layout, layout_size, text, @@ -365,7 +365,7 @@ namespace kiwano current_geometry_ = nullptr; ThrowIfFailed( - Renderer::Instance()->GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(¤t_geometry_) + Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(¤t_geometry_) ); ThrowIfFailed( diff --git a/src/kiwano/2d/DebugNode.cpp b/src/kiwano/2d/DebugNode.cpp index e0a9e5a4..4f19ba56 100644 --- a/src/kiwano/2d/DebugNode.cpp +++ b/src/kiwano/2d/DebugNode.cpp @@ -60,7 +60,7 @@ namespace kiwano void DebugNode::OnRender() { - auto renderer = Renderer::Instance(); + auto renderer = Renderer::GetInstance(); renderer->GetSolidColorBrush()->SetColor(DX::ConvertToColorF(background_color_)); renderer->GetD2DDeviceResources()->GetDeviceContext()->FillRoundedRectangle( @@ -89,9 +89,9 @@ namespace kiwano } #endif - ss << "Render: " << Renderer::Instance()->GetStatus().duration.Milliseconds() << "ms" << std::endl; + ss << "Render: " << Renderer::GetInstance()->GetStatus().duration.Milliseconds() << "ms" << std::endl; - ss << "Primitives / sec: " << Renderer::Instance()->GetStatus().primitives * frame_time_.size() << std::endl; + ss << "Primitives / sec: " << Renderer::GetInstance()->GetStatus().primitives * frame_time_.size() << std::endl; PROCESS_MEMORY_COUNTERS_EX pmc; GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)); diff --git a/src/kiwano/2d/Frame.cpp b/src/kiwano/2d/Frame.cpp index e3874078..97781255 100644 --- a/src/kiwano/2d/Frame.cpp +++ b/src/kiwano/2d/Frame.cpp @@ -39,7 +39,7 @@ namespace kiwano bool Frame::Load(Resource const& res) { - ImagePtr image = ImageCache::Instance()->AddImage(res); + ImagePtr image = ImageCache::GetInstance()->AddImage(res); if (image && image->IsValid()) { SetImage(image); diff --git a/src/kiwano/2d/GifSprite.cpp b/src/kiwano/2d/GifSprite.cpp index c4bb7c9f..5f5efe02 100644 --- a/src/kiwano/2d/GifSprite.cpp +++ b/src/kiwano/2d/GifSprite.cpp @@ -69,7 +69,7 @@ namespace kiwano if (!frame_rt_) { - auto ctx = Renderer::Instance()->GetD2DDeviceResources()->GetDeviceContext(); + auto ctx = Renderer::GetInstance()->GetD2DDeviceResources()->GetDeviceContext(); ThrowIfFailed( ctx->CreateCompatibleRenderTarget(&frame_rt_) ); @@ -105,7 +105,7 @@ namespace kiwano if (frame_to_render_) { Rect bounds = GetBounds(); - Renderer::Instance()->DrawBitmap(frame_to_render_, bounds, bounds); + Renderer::GetInstance()->DrawBitmap(frame_to_render_, bounds, bounds); } } diff --git a/src/kiwano/2d/Layer.cpp b/src/kiwano/2d/Layer.cpp index f2ffea4a..57dee16a 100644 --- a/src/kiwano/2d/Layer.cpp +++ b/src/kiwano/2d/Layer.cpp @@ -27,7 +27,7 @@ namespace kiwano Layer::Layer() : swallow_(false) { - SetSize(Renderer::Instance()->GetOutputSize()); + SetSize(Renderer::GetInstance()->GetOutputSize()); auto handler = MakeClosure(this, &Layer::HandleMessages); diff --git a/src/kiwano/2d/ShapeNode.cpp b/src/kiwano/2d/ShapeNode.cpp index d3bc288f..33142f84 100644 --- a/src/kiwano/2d/ShapeNode.cpp +++ b/src/kiwano/2d/ShapeNode.cpp @@ -129,12 +129,12 @@ namespace kiwano { if (geo_) { - Renderer::Instance()->FillGeometry( + Renderer::GetInstance()->FillGeometry( geo_, fill_color_ ); - Renderer::Instance()->DrawGeometry( + Renderer::GetInstance()->DrawGeometry( geo_, stroke_color_, stroke_width_, @@ -165,7 +165,7 @@ namespace kiwano ComPtr path_geo; ComPtr path_sink; - HRESULT hr = Renderer::Instance()->GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(&path_geo); + HRESULT hr = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(&path_geo); if (SUCCEEDED(hr)) { @@ -222,7 +222,7 @@ namespace kiwano void RectNode::SetRect(Rect const& rect) { ComPtr geo; - auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); + auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); if (SUCCEEDED(factory->CreateRectangleGeometry(DX::ConvertToRectF(rect), &geo))) { @@ -264,7 +264,7 @@ namespace kiwano void RoundedRectNode::SetRoundedRect(Rect const& rect, float radius_x, float radius_y) { ComPtr geo; - auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); + auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); if (SUCCEEDED(factory->CreateRoundedRectangleGeometry( D2D1::RoundedRect( @@ -313,7 +313,7 @@ namespace kiwano void CircleNode::SetCircle(Point const& center, float radius) { ComPtr geo; - auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); + auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); if (SUCCEEDED(factory->CreateEllipseGeometry( D2D1::Ellipse( @@ -361,7 +361,7 @@ namespace kiwano void EllipseNode::SetEllipse(Point const& center, float radius_x, float radius_y) { ComPtr geo; - auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); + auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); if (SUCCEEDED(factory->CreateEllipseGeometry( D2D1::Ellipse( @@ -393,7 +393,7 @@ namespace kiwano { current_geometry_ = nullptr; - auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); + auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); ThrowIfFailed( factory->CreatePathGeometry(¤t_geometry_) diff --git a/src/kiwano/2d/Sprite.cpp b/src/kiwano/2d/Sprite.cpp index cae843cf..1ca2abfa 100644 --- a/src/kiwano/2d/Sprite.cpp +++ b/src/kiwano/2d/Sprite.cpp @@ -87,7 +87,7 @@ namespace kiwano { if (frame_) { - Renderer::Instance()->DrawBitmap(frame_->GetImage()->GetBitmap(), frame_->GetCropRect(), GetBounds()); + Renderer::GetInstance()->DrawBitmap(frame_->GetImage()->GetBitmap(), frame_->GetCropRect(), GetBounds()); } } } diff --git a/src/kiwano/2d/Stage.cpp b/src/kiwano/2d/Stage.cpp index 97d1ba25..63a151ab 100644 --- a/src/kiwano/2d/Stage.cpp +++ b/src/kiwano/2d/Stage.cpp @@ -29,7 +29,7 @@ namespace kiwano stage_ = this; SetAnchor(0, 0); - SetSize(Renderer::Instance()->GetOutputSize()); + SetSize(Renderer::GetInstance()->GetOutputSize()); } Stage::~Stage() diff --git a/src/kiwano/2d/Text.cpp b/src/kiwano/2d/Text.cpp index 06c9f5ab..288ddcba 100644 --- a/src/kiwano/2d/Text.cpp +++ b/src/kiwano/2d/Text.cpp @@ -303,7 +303,7 @@ namespace kiwano if (text_layout_) { - auto renderer = Renderer::Instance(); + auto renderer = Renderer::GetInstance(); renderer->SetTextStyle( GetDisplayedOpacity(), style_.color, @@ -328,7 +328,7 @@ namespace kiwano if (text_.empty()) return; - auto renderer = Renderer::Instance(); + auto renderer = Renderer::GetInstance(); ThrowIfFailed( renderer->GetD2DDeviceResources()->CreateTextFormat( diff --git a/src/kiwano/2d/Transition.cpp b/src/kiwano/2d/Transition.cpp index 5a40e290..29187e31 100644 --- a/src/kiwano/2d/Transition.cpp +++ b/src/kiwano/2d/Transition.cpp @@ -66,18 +66,18 @@ namespace kiwano if (in_scene_) { ThrowIfFailed( - Renderer::Instance()->CreateLayer(in_layer_) + Renderer::GetInstance()->CreateLayer(in_layer_) ); } if (out_scene_) { ThrowIfFailed( - Renderer::Instance()->CreateLayer(out_layer_) + Renderer::GetInstance()->CreateLayer(out_layer_) ); } - window_size_ = Renderer::Instance()->GetOutputSize(); + window_size_ = Renderer::GetInstance()->GetOutputSize(); out_layer_prop_ = in_layer_prop_ = LayerProperties{ Rect(Point(), window_size_),1.f }; } @@ -101,7 +101,7 @@ namespace kiwano void Transition::Render() { - auto renderer = Renderer::Instance(); + auto renderer = Renderer::GetInstance(); if (out_scene_) { diff --git a/src/kiwano/2d/action/ActionTween.cpp b/src/kiwano/2d/action/ActionTween.cpp index 7f7c2cf6..e1f68b70 100644 --- a/src/kiwano/2d/action/ActionTween.cpp +++ b/src/kiwano/2d/action/ActionTween.cpp @@ -521,7 +521,7 @@ namespace kiwano geo_ = nullptr; geo_sink_ = nullptr; - auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetFactory(); + auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); ThrowIfFailed( factory->CreatePathGeometry(&geo_) diff --git a/src/kiwano/base/logs.h b/src/kiwano/base/logs.h index 7f5bf9cd..fff6b874 100644 --- a/src/kiwano/base/logs.h +++ b/src/kiwano/base/logs.h @@ -27,18 +27,18 @@ #ifndef KGE_LOG # ifdef KGE_DEBUG -# define KGE_LOG(FORMAT, ...) kiwano::Logger::Instance()->Messagef((FORMAT ## "\n"), __VA_ARGS__) +# define KGE_LOG(FORMAT, ...) kiwano::Logger::GetInstance()->Messagef((FORMAT ## "\n"), __VA_ARGS__) # else # define KGE_LOG __noop # endif #endif #ifndef KGE_WARNING_LOG -# define KGE_WARNING_LOG(FORMAT, ...) kiwano::Logger::Instance()->Warningf((FORMAT ## "\n"), __VA_ARGS__) +# define KGE_WARNING_LOG(FORMAT, ...) kiwano::Logger::GetInstance()->Warningf((FORMAT ## "\n"), __VA_ARGS__) #endif #ifndef KGE_ERROR_LOG -# define KGE_ERROR_LOG(FORMAT, ...) kiwano::Logger::Instance()->Errorf((FORMAT ## "\n"), __VA_ARGS__) +# define KGE_ERROR_LOG(FORMAT, ...) kiwano::Logger::GetInstance()->Errorf((FORMAT ## "\n"), __VA_ARGS__) #endif namespace kiwano @@ -274,7 +274,7 @@ namespace kiwano inline std::wostream& Logger::DefaultOutputColor(std::wostream& out) { - ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), Logger::Instance()->default_stdout_color_); + ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), Logger::GetInstance()->default_stdout_color_); return out; } } diff --git a/src/kiwano/common/Singleton.hpp b/src/kiwano/common/Singleton.hpp index a2ae5584..1ee7b14c 100644 --- a/src/kiwano/common/Singleton.hpp +++ b/src/kiwano/common/Singleton.hpp @@ -28,7 +28,7 @@ #ifndef KGE_DECLARE_SINGLETON #define KGE_DECLARE_SINGLETON( CLASS ) \ friend ::kiwano::Singleton< CLASS >; \ - friend ::std::default_delete< CLASS > + friend typename std::unique_ptr< CLASS >::deleter_type #endif namespace kiwano @@ -37,21 +37,24 @@ namespace kiwano struct Singleton { public: - static inline _Ty* Instance() + static inline _Ty* GetInstance() { if (!instance_) { - std::call_once(once_, Init); + std::call_once(once_, InitInstance); } return instance_.get(); } - static inline void Init() + static inline void InitInstance() { - if (!instance_) instance_.reset(new (std::nothrow) _Ty); + if (!instance_) + { + instance_.reset(new (std::nothrow) _Ty); + } } - static inline void Destroy() + static inline void DestroyInstance() { instance_.reset(); } diff --git a/src/kiwano/platform/Application.cpp b/src/kiwano/platform/Application.cpp index 9dbf5e2e..788ff8cf 100644 --- a/src/kiwano/platform/Application.cpp +++ b/src/kiwano/platform/Application.cpp @@ -25,6 +25,7 @@ #include "../base/input.h" #include "../base/Director.h" #include "../renderer/render.h" +#include "../utils/ResourceCache.h" #include // GET_X_LPARAM, GET_Y_LPARAM #include // ImmAssociateContext #include // std::mutex @@ -64,9 +65,9 @@ namespace kiwano ::CoInitialize(nullptr) ); - Use(Renderer::Instance()); - Use(Input::Instance()); - Use(Director::Instance()); + Use(Renderer::GetInstance()); + Use(Input::GetInstance()); + Use(Director::GetInstance()); } Application::~Application() @@ -79,7 +80,7 @@ namespace kiwano void Application::Init(const Options& options) { ThrowIfFailed( - Window::Instance()->Create( + Window::GetInstance()->Create( options.title, options.width, options.height, @@ -89,8 +90,8 @@ namespace kiwano ) ); - Renderer::Instance()->SetClearColor(options.clear_color); - Renderer::Instance()->SetVSyncEnabled(options.vsync); + Renderer::GetInstance()->SetClearColor(options.clear_color); + Renderer::GetInstance()->SetVSyncEnabled(options.vsync); // Setup all components for (Component* c : components_) @@ -100,14 +101,14 @@ namespace kiwano if (options.debug) { - Director::Instance()->ShowDebugInfo(true); - Renderer::Instance()->SetCollectingStatus(true); + Director::GetInstance()->ShowDebugInfo(true); + Renderer::GetInstance()->SetCollectingStatus(true); } // Everything is ready OnReady(); - HWND hwnd = Window::Instance()->GetHandle(); + HWND hwnd = Window::GetInstance()->GetHandle(); // disable imm ::ImmAssociateContext(hwnd, nullptr); @@ -120,7 +121,7 @@ namespace kiwano void Application::Run() { - HWND hwnd = Window::Instance()->GetHandle(); + HWND hwnd = Window::GetInstance()->GetHandle(); if (!hwnd) throw std::exception("Calling Application::Run before Application::Init"); @@ -128,7 +129,7 @@ namespace kiwano if (hwnd) { end_ = false; - Window::Instance()->Prepare(); + Window::GetInstance()->Prepare(); MSG msg = {}; while (::GetMessageW(&msg, nullptr, 0, 0) && !end_) @@ -158,13 +159,14 @@ namespace kiwano } // Destroy all instances - Director::Destroy(); - Input::Destroy(); - Renderer::Destroy(); - Window::Destroy(); + ResourceCache::DestroyInstance(); + Director::DestroyInstance(); + Input::DestroyInstance(); + Renderer::DestroyInstance(); + Window::DestroyInstance(); // DO NOT destroy Logger instance manually - // Logger::Destroy(); + // Logger::DestroyInstance(); } void Application::Use(Component* component) @@ -379,7 +381,7 @@ namespace kiwano { KGE_LOG(L"Window resized"); - Window::Instance()->UpdateWindowRect(); + Window::GetInstance()->UpdateWindowRect(); Event evt(Event::WindowResized); evt.win.width = LOWORD(lparam); @@ -405,7 +407,7 @@ namespace kiwano { bool active = (LOWORD(wparam) != WA_INACTIVE); - Window::Instance()->SetActive(active); + Window::GetInstance()->SetActive(active); Event evt(Event::WindowFocusChanged); evt.win.focus = active; diff --git a/src/kiwano/renderer/D2DDeviceResources.cpp b/src/kiwano/renderer/D2DDeviceResources.cpp index e72e7222..26626ce4 100644 --- a/src/kiwano/renderer/D2DDeviceResources.cpp +++ b/src/kiwano/renderer/D2DDeviceResources.cpp @@ -174,7 +174,7 @@ namespace kiwano void D2DDeviceResources::DiscardResources() { - ImageCache::Instance()->Clear(); + ImageCache::GetInstance()->Clear(); factory_.Reset(); device_.Reset(); diff --git a/src/kiwano/renderer/GifImage.cpp b/src/kiwano/renderer/GifImage.cpp index a2f1278a..5c6c2981 100644 --- a/src/kiwano/renderer/GifImage.cpp +++ b/src/kiwano/renderer/GifImage.cpp @@ -51,7 +51,7 @@ namespace kiwano saved_frame_.Reset(); decoder_.Reset(); - auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetWICImagingFactory(); + auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetWICImagingFactory(); if (res.IsFileType()) { @@ -124,7 +124,7 @@ namespace kiwano if (SUCCEEDED(hr)) { // Format convert to 32bppPBGRA which D2D expects - auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetWICImagingFactory(); + auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetWICImagingFactory(); hr = factory->CreateFormatConverter(&converter); } @@ -141,7 +141,7 @@ namespace kiwano if (SUCCEEDED(hr)) { - auto ctx = Renderer::Instance()->GetD2DDeviceResources()->GetDeviceContext(); + auto ctx = Renderer::GetInstance()->GetD2DDeviceResources()->GetDeviceContext(); // Create a D2DBitmap from IWICBitmapSource raw_frame_.Reset(); @@ -504,7 +504,7 @@ namespace kiwano if (SUCCEEDED(hr)) { - auto factory = Renderer::Instance()->GetD2DDeviceResources()->GetWICImagingFactory(); + auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetWICImagingFactory(); hr = factory->CreatePalette(&wic_palette); } diff --git a/src/kiwano/renderer/ImageCache.cpp b/src/kiwano/renderer/ImageCache.cpp index 7079e466..2205dc55 100644 --- a/src/kiwano/renderer/ImageCache.cpp +++ b/src/kiwano/renderer/ImageCache.cpp @@ -46,11 +46,11 @@ namespace kiwano if (res.IsFileType()) { - hr = Renderer::Instance()->GetD2DDeviceResources()->CreateBitmapFromFile(bitmap, res.GetFileName()); + hr = Renderer::GetInstance()->GetD2DDeviceResources()->CreateBitmapFromFile(bitmap, res.GetFileName()); } else { - hr = Renderer::Instance()->GetD2DDeviceResources()->CreateBitmapFromResource(bitmap, res); + hr = Renderer::GetInstance()->GetD2DDeviceResources()->CreateBitmapFromResource(bitmap, res); } if (SUCCEEDED(hr)) diff --git a/src/kiwano/renderer/render.cpp b/src/kiwano/renderer/render.cpp index 94fc2262..b05d4e35 100644 --- a/src/kiwano/renderer/render.cpp +++ b/src/kiwano/renderer/render.cpp @@ -44,7 +44,7 @@ namespace kiwano { KGE_LOG(L"Creating device resources"); - hwnd_ = Window::Instance()->GetHandle(); + hwnd_ = Window::GetInstance()->GetHandle(); ThrowIfFailed(hwnd_ ? S_OK : E_FAIL); @@ -86,7 +86,7 @@ namespace kiwano CreateDeviceResources() ); - output_size_ = Window::Instance()->GetSize(); + output_size_ = Window::GetInstance()->GetSize(); } void Renderer::DestroyComponent() diff --git a/src/kiwano/ui/Button.cpp b/src/kiwano/ui/Button.cpp index 84962b26..2f33f6f1 100644 --- a/src/kiwano/ui/Button.cpp +++ b/src/kiwano/ui/Button.cpp @@ -112,7 +112,7 @@ namespace kiwano if (evt.type == Event::MouseHover) { SetStatus(Status::Hover); - Window::Instance()->SetMouseCursor(MouseCursor::Hand); + Window::GetInstance()->SetMouseCursor(MouseCursor::Hand); if (mouse_over_callback_) mouse_over_callback_(); @@ -120,7 +120,7 @@ namespace kiwano else if (evt.type == Event::MouseOut) { SetStatus(Status::Normal); - Window::Instance()->SetMouseCursor(MouseCursor::Arrow); + Window::GetInstance()->SetMouseCursor(MouseCursor::Arrow); if (mouse_out_callback_) mouse_out_callback_(); diff --git a/src/kiwano/utils/ResourceCache.cpp b/src/kiwano/utils/ResourceCache.cpp index ae551868..fe47ea98 100644 --- a/src/kiwano/utils/ResourceCache.cpp +++ b/src/kiwano/utils/ResourceCache.cpp @@ -23,164 +23,38 @@ #include "../2d/Frame.h" #include "../2d/FrameSequence.h" #include "../renderer/GifImage.h" -#include "FileUtil.h" #include namespace kiwano { - namespace __res_loader_01 + namespace __resource_cache_01 { - struct GlobalData - { - String path; - }; - - bool LoadImagesFromData(ResourceCache* loader, GlobalData* gdata, const String* id, const String* type, - const String* file, const Array* files, int rows, int cols) - { - if (!gdata || !id) return false; - - if (file) - { - // Gif image - if (type && (*type) == L"gif") - { - return loader->AddGifImage(*id, Resource(gdata->path + (*file))); - } - - if (!(*file).empty()) - { - if (rows || cols) - { - // Frame slices - return !!loader->AddFrameSequence(*id, Resource(gdata->path + (*file)), std::max(cols, 1), std::max(rows, 1)); - } - else - { - // Simple image - return loader->AddFrame(*id, Resource(gdata->path + (*file))); - } - } - } - - // Frames - if (files) - { - Array frames; - frames.reserve(files->size()); - for (const auto& file : (*files)) - { - FramePtr frame = new Frame; - if (frame->Load(gdata->path + (file))) - { - frames.push_back(frame); - } - } - return !!loader->AddFrameSequence(*id, frames); - } - return false; - } - - bool LoadJsonData(ResourceCache* loader, Json const& json_data) - { - GlobalData global_data; - if (json_data.count(L"path")) - { - global_data.path = json_data[L"path"]; - } - - if (json_data.count(L"images")) - { - for (const auto& image : json_data[L"images"]) - { - const String* id = nullptr, *type = nullptr, *file = nullptr; - int rows = 0, cols = 0; - - if (image.count(L"id")) id = &image[L"id"].as_string(); - if (image.count(L"type")) type = &image[L"type"].as_string(); - if (image.count(L"file")) file = &image[L"file"].as_string(); - if (image.count(L"rows")) rows = image[L"rows"].as_int(); - if (image.count(L"cols")) cols = image[L"cols"].as_int(); - - if (image.count(L"files")) - { - Array files; - files.reserve(image[L"files"].size()); - for (const auto& file : image[L"files"]) - { - files.push_back(file.as_string().c_str()); - } - if (!LoadImagesFromData(loader, &global_data, id, type, file, &files, rows, cols)) - return false; - } - else - { - if (!LoadImagesFromData(loader, &global_data, id, type, file, nullptr, rows, cols)) - return false; - } - } - } - return true; - } - - bool LoadXmlData(ResourceCache* loader, tinyxml2::XMLElement* elem) - { - GlobalData global_data; - if (auto path = elem->FirstChildElement(L"path")) - { - global_data.path = path->GetText(); - } - - if (auto images = elem->FirstChildElement(L"images")) - { - for (auto image = images->FirstChildElement(); image; image = image->NextSiblingElement()) - { - String id, type, file; - int rows = 0, cols = 0; - - if (auto attr = image->Attribute(L"id")) id.assign(attr); // assign() copies attr content - if (auto attr = image->Attribute(L"type")) type = attr; // operator=() just holds attr pointer - if (auto attr = image->Attribute(L"file")) file = attr; - if (auto attr = image->IntAttribute(L"rows")) rows = attr; - if (auto attr = image->IntAttribute(L"cols")) cols = attr; - - if (file.empty() && !image->NoChildren()) - { - Array files_arr; - for (auto file = image->FirstChildElement(); file; file = file->NextSiblingElement()) - { - if (auto path = file->Attribute(L"path")) - { - files_arr.push_back(path); - } - } - if (!LoadImagesFromData(loader, &global_data, &id, &type, &file, &files_arr, rows, cols)) - return false; - } - else - { - if (!LoadImagesFromData(loader, &global_data, &id, &type, &file, nullptr, rows, cols)) - return false; - } - } - } - return true; - } + bool LoadJsonData(ResourceCache* loader, Json const& json_data); + bool LoadXmlData(ResourceCache* loader, tinyxml2::XMLElement* elem); } namespace { Map> load_json_funcs = { - { L"latest", __res_loader_01::LoadJsonData }, - { L"0.1", __res_loader_01::LoadJsonData }, + { L"latest", __resource_cache_01::LoadJsonData }, + { L"0.1", __resource_cache_01::LoadJsonData }, }; Map> load_xml_funcs = { - { L"latest", __res_loader_01::LoadXmlData }, - { L"0.1", __res_loader_01::LoadXmlData }, + { L"latest", __resource_cache_01::LoadXmlData }, + { L"0.1", __resource_cache_01::LoadXmlData }, }; } + ResourceCache::ResourceCache() + { + } + + ResourceCache::~ResourceCache() + { + Clear(); + } + bool ResourceCache::LoadFromJsonFile(String const& file_path) { Json json_data; @@ -479,18 +353,152 @@ namespace kiwano cache_.erase(id); } - void ResourceCache::Destroy() + void ResourceCache::Clear() { cache_.clear(); } - ResourceCache::ResourceCache() - { - } - - ResourceCache::~ResourceCache() - { - Destroy(); - } - +} + +namespace kiwano +{ + namespace __resource_cache_01 + { + struct GlobalData + { + String path; + }; + + bool LoadImagesFromData(ResourceCache* loader, GlobalData* gdata, const String* id, const String* type, + const String* file, const Array* files, int rows, int cols) + { + if (!gdata || !id) return false; + + if (file) + { + // Gif image + if (type && (*type) == L"gif") + { + return loader->AddGifImage(*id, Resource(gdata->path + (*file))); + } + + if (!(*file).empty()) + { + if (rows || cols) + { + // Frame slices + return !!loader->AddFrameSequence(*id, Resource(gdata->path + (*file)), std::max(cols, 1), std::max(rows, 1)); + } + else + { + // Simple image + return loader->AddFrame(*id, Resource(gdata->path + (*file))); + } + } + } + + // Frames + if (files) + { + Array frames; + frames.reserve(files->size()); + for (const auto& file : (*files)) + { + FramePtr frame = new Frame; + if (frame->Load(gdata->path + (file))) + { + frames.push_back(frame); + } + } + return !!loader->AddFrameSequence(*id, frames); + } + return false; + } + + bool LoadJsonData(ResourceCache* loader, Json const& json_data) + { + GlobalData global_data; + if (json_data.count(L"path")) + { + global_data.path = json_data[L"path"]; + } + + if (json_data.count(L"images")) + { + for (const auto& image : json_data[L"images"]) + { + const String* id = nullptr, * type = nullptr, * file = nullptr; + int rows = 0, cols = 0; + + if (image.count(L"id")) id = &image[L"id"].as_string(); + if (image.count(L"type")) type = &image[L"type"].as_string(); + if (image.count(L"file")) file = &image[L"file"].as_string(); + if (image.count(L"rows")) rows = image[L"rows"].as_int(); + if (image.count(L"cols")) cols = image[L"cols"].as_int(); + + if (image.count(L"files")) + { + Array files; + files.reserve(image[L"files"].size()); + for (const auto& file : image[L"files"]) + { + files.push_back(file.as_string().c_str()); + } + if (!LoadImagesFromData(loader, &global_data, id, type, file, &files, rows, cols)) + return false; + } + else + { + if (!LoadImagesFromData(loader, &global_data, id, type, file, nullptr, rows, cols)) + return false; + } + } + } + return true; + } + + bool LoadXmlData(ResourceCache* loader, tinyxml2::XMLElement* elem) + { + GlobalData global_data; + if (auto path = elem->FirstChildElement(L"path")) + { + global_data.path = path->GetText(); + } + + if (auto images = elem->FirstChildElement(L"images")) + { + for (auto image = images->FirstChildElement(); image; image = image->NextSiblingElement()) + { + String id, type, file; + int rows = 0, cols = 0; + + if (auto attr = image->Attribute(L"id")) id.assign(attr); // assign() copies attr content + if (auto attr = image->Attribute(L"type")) type = attr; // operator=() just holds attr pointer + if (auto attr = image->Attribute(L"file")) file = attr; + if (auto attr = image->IntAttribute(L"rows")) rows = attr; + if (auto attr = image->IntAttribute(L"cols")) cols = attr; + + if (file.empty() && !image->NoChildren()) + { + Array files_arr; + for (auto file = image->FirstChildElement(); file; file = file->NextSiblingElement()) + { + if (auto path = file->Attribute(L"path")) + { + files_arr.push_back(path); + } + } + if (!LoadImagesFromData(loader, &global_data, &id, &type, &file, &files_arr, rows, cols)) + return false; + } + else + { + if (!LoadImagesFromData(loader, &global_data, &id, &type, &file, nullptr, rows, cols)) + return false; + } + } + } + return true; + } + } } diff --git a/src/kiwano/utils/ResourceCache.h b/src/kiwano/utils/ResourceCache.h index 0fca758d..7f78b877 100644 --- a/src/kiwano/utils/ResourceCache.h +++ b/src/kiwano/utils/ResourceCache.h @@ -22,6 +22,7 @@ #include "../macros.h" #include "../common/helper.h" #include "../common/Json.hpp" +#include "../common/Singleton.hpp" #include "../base/Resource.h" #include "../2d/include-forwards.h" #include "../renderer/GifImage.h" @@ -31,7 +32,10 @@ namespace kiwano { // 资源缓存 class KGE_API ResourceCache + : public Singleton { + KGE_DECLARE_SINGLETON(ResourceCache); + public: // 从 JSON 文件加载资源信息 bool LoadFromJsonFile(String const& file_path); @@ -89,8 +93,8 @@ namespace kiwano // 删除指定资源 void Delete(String const& id); - // 销毁所有资源 - void Destroy(); + // 清空所有资源 + void Clear(); template _Ty* Get(String const& id) const @@ -101,7 +105,7 @@ namespace kiwano return dynamic_cast<_Ty*>((*iter).second.Get()); } - public: + protected: ResourceCache(); virtual ~ResourceCache(); From ed034750fef2f556f783e37831136d2af1788e22 Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Tue, 13 Aug 2019 21:16:38 +0800 Subject: [PATCH 03/11] refactor core module --- projects/kiwano.vcxproj | 20 +- projects/kiwano.vcxproj.filters | 66 +- src/kiwano-audio/src/Player.h | 2 +- src/kiwano-audio/src/Sound.h | 2 +- src/kiwano-audio/src/Transcoder.cpp | 16 +- src/kiwano-audio/src/audio.h | 2 +- src/kiwano-imgui/src/ImGuiLayer.h | 2 +- src/kiwano-imgui/src/ImGuiModule.cpp | 6 +- src/kiwano-imgui/src/ImGuiModule.h | 2 +- src/kiwano-imgui/src/imgui_impl_dx10.cpp | 2 +- src/kiwano-imgui/src/imgui_impl_dx11.cpp | 2 +- src/kiwano-network/src/HttpClient.cpp | 16 +- src/kiwano-network/src/HttpClient.h | 4 +- src/kiwano-network/src/HttpRequest.hpp | 6 +- src/kiwano-network/src/HttpResponse.hpp | 4 +- src/kiwano/2d/Actor.cpp | 72 +- src/kiwano/2d/Actor.h | 12 +- src/kiwano/2d/Canvas.cpp | 46 +- src/kiwano/2d/Canvas.h | 2 +- src/kiwano/2d/DebugNode.cpp | 2 +- src/kiwano/2d/DebugNode.h | 2 +- src/kiwano/2d/FrameSequence.cpp | 6 +- src/kiwano/2d/FrameSequence.h | 8 +- src/kiwano/2d/GifSprite.cpp | 2 +- src/kiwano/2d/GifSprite.h | 4 +- src/kiwano/2d/Layer.cpp | 6 +- src/kiwano/2d/ShapeNode.cpp | 2 +- src/kiwano/2d/ShapeNode.h | 2 +- src/kiwano/2d/action/Action.h | 6 +- src/kiwano/2d/action/ActionGroup.cpp | 22 +- src/kiwano/2d/action/ActionGroup.h | 10 +- src/kiwano/2d/action/ActionHelper.h | 10 +- src/kiwano/2d/action/ActionManager.cpp | 26 +- src/kiwano/2d/action/ActionManager.h | 2 +- src/kiwano/2d/action/ActionTween.cpp | 2 +- src/kiwano/2d/action/ActionTween.h | 6 +- src/kiwano/2d/action/Animation.cpp | 4 +- src/kiwano/2d/include-forwards.h | 7 +- src/kiwano/base/AsyncTask.cpp | 4 +- src/kiwano/base/AsyncTask.h | 5 +- src/kiwano/{common => base}/ComPtr.hpp | 4 +- src/kiwano/base/Director.cpp | 26 +- src/kiwano/base/Director.h | 6 +- src/kiwano/base/EventDispatcher.cpp | 30 +- src/kiwano/base/EventDispatcher.h | 2 +- src/kiwano/base/EventListener.h | 11 +- src/kiwano/base/Input.h | 2 +- src/kiwano/base/Object.cpp | 4 +- src/kiwano/base/Object.h | 4 +- src/kiwano/base/RefCounter.hpp | 4 +- src/kiwano/base/Resource.h | 2 +- src/kiwano/base/SmartPtr.hpp | 4 +- src/kiwano/base/Timer.h | 9 +- src/kiwano/base/TimerManager.cpp | 36 +- src/kiwano/base/TimerManager.h | 2 +- src/kiwano/base/logs.h | 2 +- src/kiwano/base/time.cpp | 2 +- src/kiwano/base/time.h | 2 +- src/kiwano/base/window.h | 3 +- src/kiwano/common/Array.hpp | 277 -- src/kiwano/common/IntrusiveList.hpp | 255 -- src/kiwano/common/IntrusivePtr.hpp | 212 -- src/kiwano/common/Json.hpp | 2758 ----------------- src/kiwano/common/String.hpp | 1736 ----------- src/kiwano/common/closure.hpp | 344 -- src/kiwano/core/basic_json.hpp | 2737 ++++++++++++++++ src/kiwano/{common/helper.h => core/core.h} | 55 +- src/kiwano/core/function.hpp | 353 +++ src/kiwano/core/intrusive_list.hpp | 261 ++ src/kiwano/core/intrusive_ptr.hpp | 222 ++ .../Noncopyable.hpp => core/noncopyable.hpp} | 23 +- .../Singleton.hpp => core/singleton.hpp} | 75 +- src/kiwano/core/string.hpp | 1741 +++++++++++ src/kiwano/core/vector.hpp | 288 ++ src/kiwano/kiwano.h | 24 +- src/kiwano/math/Rect.hpp | 2 +- src/kiwano/platform/Application.cpp | 13 +- src/kiwano/platform/Application.h | 11 +- src/kiwano/renderer/D2DDeviceResources.cpp | 42 +- src/kiwano/renderer/D2DDeviceResources.h | 12 +- src/kiwano/renderer/D3D10DeviceResources.cpp | 32 +- src/kiwano/renderer/D3D10DeviceResources.h | 10 +- src/kiwano/renderer/D3D11DeviceResources.cpp | 34 +- src/kiwano/renderer/D3D11DeviceResources.h | 12 +- src/kiwano/renderer/GifImage.cpp | 20 +- src/kiwano/renderer/ImageCache.cpp | 1 + src/kiwano/renderer/ImageCache.h | 2 +- src/kiwano/renderer/helper.hpp | 2 +- src/kiwano/renderer/render.cpp | 38 +- src/kiwano/renderer/render.h | 8 +- src/kiwano/third-party/tinyxml2/tinyxml2.h | 2 - src/kiwano/ui/Button.cpp | 8 +- src/kiwano/ui/Button.h | 2 +- src/kiwano/ui/Menu.cpp | 4 +- src/kiwano/ui/Menu.h | 6 +- src/kiwano/utils/DataUtil.h | 2 +- src/kiwano/utils/FileUtil.h | 1 - src/kiwano/utils/Path.h | 2 +- src/kiwano/utils/ResourceCache.cpp | 24 +- src/kiwano/utils/ResourceCache.h | 11 +- 100 files changed, 6150 insertions(+), 6089 deletions(-) rename src/kiwano/{common => base}/ComPtr.hpp (94%) delete mode 100644 src/kiwano/common/Array.hpp delete mode 100644 src/kiwano/common/IntrusiveList.hpp delete mode 100644 src/kiwano/common/IntrusivePtr.hpp delete mode 100644 src/kiwano/common/Json.hpp delete mode 100644 src/kiwano/common/String.hpp delete mode 100644 src/kiwano/common/closure.hpp create mode 100644 src/kiwano/core/basic_json.hpp rename src/kiwano/{common/helper.h => core/core.h} (57%) create mode 100644 src/kiwano/core/function.hpp create mode 100644 src/kiwano/core/intrusive_list.hpp create mode 100644 src/kiwano/core/intrusive_ptr.hpp rename src/kiwano/{common/Noncopyable.hpp => core/noncopyable.hpp} (82%) rename src/kiwano/{common/Singleton.hpp => core/singleton.hpp} (66%) create mode 100644 src/kiwano/core/string.hpp create mode 100644 src/kiwano/core/vector.hpp diff --git a/projects/kiwano.vcxproj b/projects/kiwano.vcxproj index 1cba2a48..bde09f16 100644 --- a/projects/kiwano.vcxproj +++ b/projects/kiwano.vcxproj @@ -9,8 +9,18 @@ + + + + + + + + + + @@ -45,16 +55,6 @@ - - - - - - - - - - diff --git a/projects/kiwano.vcxproj.filters b/projects/kiwano.vcxproj.filters index 0233eb9b..2b600e84 100644 --- a/projects/kiwano.vcxproj.filters +++ b/projects/kiwano.vcxproj.filters @@ -10,9 +10,6 @@ {07b6d541-4a1b-472a-aae0-daf9d082fe84} - - {86e2d0f2-a9d0-4456-b6a5-d480228bbf82} - {c2654ccc-59f6-4c17-bb6b-99b07fc78702} @@ -37,6 +34,9 @@ {9314f30d-5742-48b6-94e5-e3b4284106f6} + + {86e2d0f2-a9d0-4456-b6a5-d480228bbf82} + @@ -78,21 +78,6 @@ 2d - - common - - - common - - - common - - - common - - - common - base @@ -213,21 +198,6 @@ 2d - - common - - - common - - - common - - - common - - - common - third-party\tinyxml2 @@ -279,6 +249,36 @@ 2d + + core + + + core + + + core + + + core + + + core + + + core + + + core + + + core + + + base + + + core + diff --git a/src/kiwano-audio/src/Player.h b/src/kiwano-audio/src/Player.h index 42286b8b..290c7de7 100644 --- a/src/kiwano-audio/src/Player.h +++ b/src/kiwano-audio/src/Player.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include +#include #include #include "Sound.h" diff --git a/src/kiwano-audio/src/Sound.h b/src/kiwano-audio/src/Sound.h index 2f982c2e..fa505676 100644 --- a/src/kiwano-audio/src/Sound.h +++ b/src/kiwano-audio/src/Sound.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include +#include #include #include #include diff --git a/src/kiwano-audio/src/Transcoder.cpp b/src/kiwano-audio/src/Transcoder.cpp index c1b676ec..3f70722f 100644 --- a/src/kiwano-audio/src/Transcoder.cpp +++ b/src/kiwano-audio/src/Transcoder.cpp @@ -23,8 +23,8 @@ #endif #include -#include -#include +#include +#include #include #include #include @@ -69,7 +69,7 @@ namespace kiwano if (SUCCEEDED(hr)) { - hr = ReadSource(reader.Get(), wave_data, wave_data_size); + hr = ReadSource(reader.get(), wave_data, wave_data_size); } return hr; @@ -100,13 +100,13 @@ namespace kiwano if (SUCCEEDED(hr)) { - hr = modules::MediaFoundation::Get().MFCreateMFByteStreamOnStream(stream.Get(), &byte_stream); + hr = modules::MediaFoundation::Get().MFCreateMFByteStreamOnStream(stream.get(), &byte_stream); } if (SUCCEEDED(hr)) { hr = modules::MediaFoundation::Get().MFCreateSourceReaderFromByteStream( - byte_stream.Get(), + byte_stream.get(), nullptr, &reader ); @@ -114,7 +114,7 @@ namespace kiwano if (SUCCEEDED(hr)) { - hr = ReadSource(reader.Get(), wave_data, wave_data_size); + hr = ReadSource(reader.get(), wave_data, wave_data_size); } return hr; @@ -146,7 +146,7 @@ namespace kiwano hr = reader->SetCurrentMediaType( (DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, 0, - partial_type.Get() + partial_type.get() ); } @@ -173,7 +173,7 @@ namespace kiwano { UINT32 size = 0; hr = modules::MediaFoundation::Get().MFCreateWaveFormatExFromMFMediaType( - uncompressed_type.Get(), + uncompressed_type.get(), &wave_format_, &size, (DWORD)MFWaveFormatExConvertFlag_Normal diff --git a/src/kiwano-audio/src/audio.h b/src/kiwano-audio/src/audio.h index 5ec3ffe4..91ddbf08 100644 --- a/src/kiwano-audio/src/audio.h +++ b/src/kiwano-audio/src/audio.h @@ -19,7 +19,7 @@ // THE SOFTWARE. #pragma once -#include +#include #include namespace kiwano diff --git a/src/kiwano-imgui/src/ImGuiLayer.h b/src/kiwano-imgui/src/ImGuiLayer.h index ea84f668..72477508 100644 --- a/src/kiwano-imgui/src/ImGuiLayer.h +++ b/src/kiwano-imgui/src/ImGuiLayer.h @@ -27,7 +27,7 @@ namespace kiwano { KGE_DECLARE_SMART_PTR(ImGuiLayer); - using ImGuiPipeline = Closure; + using ImGuiPipeline = Function; class ImGuiLayer : public Layer diff --git a/src/kiwano-imgui/src/ImGuiModule.cpp b/src/kiwano-imgui/src/ImGuiModule.cpp index da5f8baa..9a7b68aa 100644 --- a/src/kiwano-imgui/src/ImGuiModule.cpp +++ b/src/kiwano-imgui/src/ImGuiModule.cpp @@ -1,8 +1,8 @@ // Copyright (C) 2019 Nomango -#include -#include -#include +#include +#include +#include #include #include #include diff --git a/src/kiwano-imgui/src/ImGuiModule.h b/src/kiwano-imgui/src/ImGuiModule.h index ae0b0c0b..553afc11 100644 --- a/src/kiwano-imgui/src/ImGuiModule.h +++ b/src/kiwano-imgui/src/ImGuiModule.h @@ -20,7 +20,7 @@ #pragma once #include -#include +#include namespace kiwano { diff --git a/src/kiwano-imgui/src/imgui_impl_dx10.cpp b/src/kiwano-imgui/src/imgui_impl_dx10.cpp index ed6fa680..e0d068fa 100644 --- a/src/kiwano-imgui/src/imgui_impl_dx10.cpp +++ b/src/kiwano-imgui/src/imgui_impl_dx10.cpp @@ -35,7 +35,7 @@ struct VERTEX_CONSTANT_BUFFER float mvp[4][4]; }; -// Render function +// Render Function // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) { diff --git a/src/kiwano-imgui/src/imgui_impl_dx11.cpp b/src/kiwano-imgui/src/imgui_impl_dx11.cpp index f09218da..a5586bf4 100644 --- a/src/kiwano-imgui/src/imgui_impl_dx11.cpp +++ b/src/kiwano-imgui/src/imgui_impl_dx11.cpp @@ -36,7 +36,7 @@ struct VERTEX_CONSTANT_BUFFER float mvp[4][4]; }; -// Render function +// Render Function // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) { diff --git a/src/kiwano-network/src/HttpClient.cpp b/src/kiwano-network/src/HttpClient.cpp index d5d01c25..8dd8a82c 100644 --- a/src/kiwano-network/src/HttpClient.cpp +++ b/src/kiwano-network/src/HttpClient.cpp @@ -105,7 +105,7 @@ namespace } } - bool Init(HttpClient* client, Array const& headers, kiwano::string const& url, kiwano::string* response_data, kiwano::string* response_header, char* error_buffer) + bool Init(HttpClient* client, Vector const& headers, kiwano::string const& url, kiwano::string* response_data, kiwano::string* response_header, char* error_buffer) { if (!SetOption(CURLOPT_ERRORBUFFER, error_buffer)) return false; @@ -171,7 +171,7 @@ namespace public: static inline bool GetRequest( HttpClient* client, - Array const& headers, + Vector const& headers, kiwano::string const& url, long* response_code, kiwano::string* response_data, @@ -186,7 +186,7 @@ namespace static inline bool PostRequest( HttpClient* client, - Array const& headers, + Vector const& headers, kiwano::string const& url, kiwano::string const& request_data, long* response_code, @@ -204,7 +204,7 @@ namespace static inline bool PutRequest( HttpClient* client, - Array const& headers, + Vector const& headers, kiwano::string const& url, kiwano::string const& request_data, long* response_code, @@ -222,7 +222,7 @@ namespace static inline bool DeleteRequest( HttpClient* client, - Array const& headers, + Vector const& headers, kiwano::string const& url, long* response_code, kiwano::string* response_data, @@ -256,7 +256,7 @@ namespace kiwano { ::curl_global_init(CURL_GLOBAL_ALL); - std::thread thread(MakeClosure(this, &HttpClient::NetworkThread)); + std::thread thread(bind_func(this, &HttpClient::NetworkThread)); thread.detach(); } @@ -299,7 +299,7 @@ namespace kiwano response_queue_.push(response); response_mutex_.unlock(); - Application::PreformInMainThread(MakeClosure(this, &HttpClient::DispatchResponseCallback)); + Application::PreformInMainThread(bind_func(this, &HttpClient::DispatchResponseCallback)); } } @@ -314,7 +314,7 @@ namespace kiwano kiwano::string url = convert_to_utf8(request->GetUrl()); kiwano::string data = convert_to_utf8(request->GetData()); - Array headers; + Vector headers; headers.reserve(request->GetHeaders().size()); for (const auto& pair : request->GetHeaders()) { diff --git a/src/kiwano-network/src/HttpClient.h b/src/kiwano-network/src/HttpClient.h index e587d56d..a026705d 100644 --- a/src/kiwano-network/src/HttpClient.h +++ b/src/kiwano-network/src/HttpClient.h @@ -19,8 +19,8 @@ // THE SOFTWARE. #pragma once -#include -#include +#include +#include #include #include #include diff --git a/src/kiwano-network/src/HttpRequest.hpp b/src/kiwano-network/src/HttpRequest.hpp index a7be4ed9..79335b4f 100644 --- a/src/kiwano-network/src/HttpRequest.hpp +++ b/src/kiwano-network/src/HttpRequest.hpp @@ -19,15 +19,15 @@ // THE SOFTWARE. #pragma once -#include -#include +#include +#include #include namespace kiwano { namespace network { - typedef Closure ResponseCallback; + typedef Function ResponseCallback; class KGE_API HttpRequest : public Object diff --git a/src/kiwano-network/src/HttpResponse.hpp b/src/kiwano-network/src/HttpResponse.hpp index da51c093..094361b4 100644 --- a/src/kiwano-network/src/HttpResponse.hpp +++ b/src/kiwano-network/src/HttpResponse.hpp @@ -19,8 +19,8 @@ // THE SOFTWARE. #pragma once -#include -#include +#include +#include #include namespace kiwano diff --git a/src/kiwano/2d/Actor.cpp b/src/kiwano/2d/Actor.cpp index 485321a3..3b162827 100644 --- a/src/kiwano/2d/Actor.cpp +++ b/src/kiwano/2d/Actor.cpp @@ -71,12 +71,12 @@ namespace kiwano OnUpdate(dt); } - if (!children_.IsEmpty()) + if (!children_.is_empty()) { ActorPtr next; - for (auto child = children_.First(); child; child = next) + for (auto child = children_.first_item(); child; child = next) { - next = child->NextItem(); + next = child->next_item(); child->Update(dt); } } @@ -89,7 +89,7 @@ namespace kiwano UpdateTransform(); - if (children_.IsEmpty()) + if (children_.is_empty()) { PrepareRender(); OnRender(); @@ -97,14 +97,14 @@ namespace kiwano else { // render children those are less than 0 in Z-Order - Actor* child = children_.First().Get(); + Actor* child = children_.first_item().get(); while (child) { if (child->GetZOrder() >= 0) break; child->Render(); - child = child->NextItem().Get(); + child = child->next_item().get(); } PrepareRender(); @@ -113,7 +113,7 @@ namespace kiwano while (child) { child->Render(); - child = child->NextItem().Get(); + child = child->next_item().get(); } } } @@ -130,7 +130,7 @@ namespace kiwano renderer->DrawRectangle(bounds, Color(Color::Red, .8f), 4.f); } - for (auto child = children_.First(); child; child = child->NextItem()) + for (auto child = children_.first_item(); child; child = child->next_item()) { child->RenderBorder(); } @@ -142,9 +142,9 @@ namespace kiwano return; ActorPtr prev; - for (auto child = children_.Last(); child; child = prev) + for (auto child = children_.last_item(); child; child = prev) { - prev = child->PrevItem(); + prev = child->prev_item(); child->Dispatch(evt); } @@ -245,7 +245,7 @@ namespace kiwano } // update children's transform - for (Actor* child = children_.First().Get(); child; child = child->NextItem().Get()) + for (Actor* child = children_.first_item().get(); child; child = child->next_item().get()) child->dirty_transform_ = true; } @@ -260,7 +260,7 @@ namespace kiwano displayed_opacity_ = opacity_; } - for (Actor* child = children_.First().Get(); child; child = child->NextItem().Get()) + for (Actor* child = children_.first_item().get(); child; child = child->next_item().get()) { child->UpdateOpacity(); } @@ -271,7 +271,7 @@ namespace kiwano if (scene && stage_ != scene) { stage_ = scene; - for (Actor* child = children_.First().Get(); child; child = child->NextItem().Get()) + for (Actor* child = children_.first_item().get(); child; child = child->next_item().get()) { child->stage_ = scene; } @@ -284,28 +284,28 @@ namespace kiwano { ActorPtr me = this; - parent_->children_.Remove(me); + parent_->children_.remove_item(me); - Actor* sibling = parent_->children_.Last().Get(); + Actor* sibling = parent_->children_.last_item().get(); if (sibling && sibling->GetZOrder() > z_order_) { - sibling = sibling->PrevItem().Get(); + sibling = sibling->prev_item().get(); while (sibling) { if (sibling->GetZOrder() <= z_order_) break; - sibling = sibling->PrevItem().Get(); + sibling = sibling->prev_item().get(); } } if (sibling) { - parent_->children_.InsertAfter(me, sibling); + parent_->children_.insert_after(me, sibling); } else { - parent_->children_.PushFront(me); + parent_->children_.push_front_item(me); } } } @@ -519,15 +519,15 @@ namespace kiwano #ifdef KGE_DEBUG if (child->parent_) - KGE_ERROR_LOG(L"The node to be added already has a parent"); + KGE_ERROR_LOG(L"The actor to be added already has a parent"); for (Actor* parent = parent_; parent; parent = parent->parent_) if (parent == child) - KGE_ERROR_LOG(L"A node cannot be its own parent"); + KGE_ERROR_LOG(L"A actor cannot be its own parent"); #endif // KGE_DEBUG - children_.PushBack(child); + children_.push_back_item(child); child->parent_ = this; child->SetStage(this->stage_); child->dirty_transform_ = true; @@ -536,11 +536,11 @@ namespace kiwano } } - void Actor::AddChildren(Array const& children) + void Actor::AddChildren(Vector const& children) { - for (const auto& node : children) + for (const auto& actor : children) { - this->AddChild(node); + this->AddChild(actor); } } @@ -554,12 +554,12 @@ namespace kiwano return GetTransformMatrix().Transform(GetBounds()); } - Array Actor::GetChildren(String const& name) const + Vector Actor::GetChildren(String const& name) const { - Array children; + Vector children; size_t hash_code = std::hash{}(name); - for (Actor* child = children_.First().Get(); child; child = child->NextItem().Get()) + for (Actor* child = children_.first_item().get(); child; child = child->next_item().get()) { if (child->hash_name_ == hash_code && child->IsName(name)) { @@ -573,7 +573,7 @@ namespace kiwano { size_t hash_code = std::hash{}(name); - for (Actor* child = children_.First().Get(); child; child = child->NextItem().Get()) + for (Actor* child = children_.first_item().get(); child; child = child->next_item().get()) { if (child->hash_name_ == hash_code && child->IsName(name)) { @@ -598,27 +598,27 @@ namespace kiwano void Actor::RemoveChild(ActorPtr child) { - RemoveChild(child.Get()); + RemoveChild(child.get()); } void Actor::RemoveChild(Actor * child) { KGE_ASSERT(child && "Actor::RemoveChild failed, NULL pointer exception"); - if (children_.IsEmpty()) + if (children_.is_empty()) return; if (child) { child->parent_ = nullptr; if (child->stage_) child->SetStage(nullptr); - children_.Remove(ActorPtr(child)); + children_.remove_item(ActorPtr(child)); } } void Actor::RemoveChildren(String const& child_name) { - if (children_.IsEmpty()) + if (children_.is_empty()) { return; } @@ -626,9 +626,9 @@ namespace kiwano size_t hash_code = std::hash{}(child_name); Actor* next; - for (Actor* child = children_.First().Get(); child; child = next) + for (Actor* child = children_.first_item().get(); child; child = next) { - next = child->NextItem().Get(); + next = child->next_item().get(); if (child->hash_name_ == hash_code && child->IsName(child_name)) { @@ -639,7 +639,7 @@ namespace kiwano void Actor::RemoveAllChildren() { - children_.Clear(); + children_.clear_items(); } void Actor::SetResponsible(bool enable) diff --git a/src/kiwano/2d/Actor.h b/src/kiwano/2d/Actor.h index e5b096f6..0075b65b 100644 --- a/src/kiwano/2d/Actor.h +++ b/src/kiwano/2d/Actor.h @@ -35,14 +35,14 @@ namespace kiwano , public TimerManager , public ActionManager , public EventDispatcher - , public IntrusiveListItem + , public intrusive_list_item { friend class Director; friend class Transition; - friend class IntrusiveList; + friend class intrusive_list; - using Children = IntrusiveList; - using UpdateCallback = Closure; + using Children = intrusive_list; + using UpdateCallback = Function; public: Actor(); @@ -342,11 +342,11 @@ namespace kiwano // 添加多个子角色 void AddChildren( - Array const& children + Vector const& children ); // 获取所有名称相同的子角色 - Array GetChildren( + Vector GetChildren( String const& name ) const; diff --git a/src/kiwano/2d/Canvas.cpp b/src/kiwano/2d/Canvas.cpp index d1e652f5..623cdbfc 100644 --- a/src/kiwano/2d/Canvas.cpp +++ b/src/kiwano/2d/Canvas.cpp @@ -51,7 +51,7 @@ namespace kiwano ThrowIfFailed( ITextRenderer::Create( &text_renderer_, - render_target_.Get() + render_target_.get() ) ); @@ -169,9 +169,9 @@ namespace kiwano render_target_->DrawLine( D2D1::Point2F(begin.x, begin.y), D2D1::Point2F(end.x, end.y), - stroke_brush_.Get(), + stroke_brush_.get(), stroke_width_, - outline_join_style_.Get() + outline_join_style_.get() ); cache_expired_ = true; } @@ -187,9 +187,9 @@ namespace kiwano radius, radius ), - stroke_brush_.Get(), + stroke_brush_.get(), stroke_width_, - outline_join_style_.Get() + outline_join_style_.get() ); cache_expired_ = true; } @@ -205,9 +205,9 @@ namespace kiwano radius_x, radius_y ), - stroke_brush_.Get(), + stroke_brush_.get(), stroke_width_, - outline_join_style_.Get() + outline_join_style_.get() ); cache_expired_ = true; } @@ -221,9 +221,9 @@ namespace kiwano rect.origin.x + rect.size.x, rect.origin.y + rect.size.y ), - stroke_brush_.Get(), + stroke_brush_.get(), stroke_width_, - outline_join_style_.Get() + outline_join_style_.get() ); cache_expired_ = true; } @@ -241,9 +241,9 @@ namespace kiwano radius_x, radius_y ), - stroke_brush_.Get(), + stroke_brush_.get(), stroke_width_, - outline_join_style_.Get() + outline_join_style_.get() ); cache_expired_ = true; } @@ -253,7 +253,7 @@ namespace kiwano if (image && image->GetBitmap()) { render_target_->DrawBitmap( - image->GetBitmap().Get(), + image->GetBitmap().get(), D2D1::RectF(0, 0, image->GetWidth(), image->GetHeight()), opacity, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, @@ -292,7 +292,7 @@ namespace kiwano ); ThrowIfFailed( - text_layout->Draw(nullptr, text_renderer_.Get(), point.x, point.y) + text_layout->Draw(nullptr, text_renderer_.get(), point.x, point.y) ); } @@ -307,7 +307,7 @@ namespace kiwano radius, radius ), - fill_brush_.Get() + fill_brush_.get() ); cache_expired_ = true; } @@ -323,7 +323,7 @@ namespace kiwano radius_x, radius_y ), - fill_brush_.Get() + fill_brush_.get() ); cache_expired_ = true; } @@ -337,7 +337,7 @@ namespace kiwano rect.origin.x + rect.size.x, rect.origin.y + rect.size.y ), - fill_brush_.Get() + fill_brush_.get() ); cache_expired_ = true; } @@ -355,7 +355,7 @@ namespace kiwano radius_x, radius_y ), - fill_brush_.Get() + fill_brush_.get() ); cache_expired_ = true; } @@ -393,7 +393,7 @@ namespace kiwano current_sink_->AddLine(DX::ConvertToPoint2F(point)); } - void Canvas::AddLines(Array const& points) + void Canvas::AddLines(Vector const& points) { if (current_sink_ && !points.empty()) { @@ -437,10 +437,10 @@ namespace kiwano void Canvas::StrokePath() { render_target_->DrawGeometry( - current_geometry_.Get(), - stroke_brush_.Get(), + current_geometry_.get(), + stroke_brush_.get(), stroke_width_, - outline_join_style_.Get() + outline_join_style_.get() ); cache_expired_ = true; } @@ -448,8 +448,8 @@ namespace kiwano void Canvas::FillPath() { render_target_->FillGeometry( - current_geometry_.Get(), - fill_brush_.Get() + current_geometry_.get(), + fill_brush_.get() ); cache_expired_ = true; } diff --git a/src/kiwano/2d/Canvas.h b/src/kiwano/2d/Canvas.h index 210558a0..4defcae0 100644 --- a/src/kiwano/2d/Canvas.h +++ b/src/kiwano/2d/Canvas.h @@ -140,7 +140,7 @@ namespace kiwano // 添加多条线段 void AddLines( - Array const& points + Vector const& points ); // 添加一条三次方贝塞尔曲线 diff --git a/src/kiwano/2d/DebugNode.cpp b/src/kiwano/2d/DebugNode.cpp index 4f19ba56..6efa20e8 100644 --- a/src/kiwano/2d/DebugNode.cpp +++ b/src/kiwano/2d/DebugNode.cpp @@ -31,7 +31,7 @@ namespace kiwano DebugNode::DebugNode() : background_color_(0.0f, 0.0f, 0.0f, 0.7f) { - SetName(L"kiwano-debug-node"); + SetName(L"kiwano-debug-actor"); SetPosition(10, 10); SetResponsible(true); SetCascadeOpacityEnabled(true); diff --git a/src/kiwano/2d/DebugNode.h b/src/kiwano/2d/DebugNode.h index 320448a1..519868c5 100644 --- a/src/kiwano/2d/DebugNode.h +++ b/src/kiwano/2d/DebugNode.h @@ -38,6 +38,6 @@ namespace kiwano protected: Color background_color_; TextPtr debug_text_; - Array @@ -293,9 +293,6 @@ 2d - - 2d - 2d @@ -380,9 +377,6 @@ third-party\tinyxml2 - - 2d - base @@ -425,5 +419,11 @@ 2d + + 2d + + + 2d + \ No newline at end of file diff --git a/src/kiwano/2d/DebugNode.cpp b/src/kiwano/2d/DebugActor.cpp similarity index 99% rename from src/kiwano/2d/DebugNode.cpp rename to src/kiwano/2d/DebugActor.cpp index 6efa20e8..604c172a 100644 --- a/src/kiwano/2d/DebugNode.cpp +++ b/src/kiwano/2d/DebugActor.cpp @@ -18,7 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include "DebugNode.h" +#include "DebugActor.h" #include "Text.h" #include "../renderer/render.h" #include diff --git a/src/kiwano/2d/DebugNode.h b/src/kiwano/2d/DebugActor.h similarity index 100% rename from src/kiwano/2d/DebugNode.h rename to src/kiwano/2d/DebugActor.h diff --git a/src/kiwano/2d/ShapeNode.cpp b/src/kiwano/2d/ShapeActor.cpp similarity index 74% rename from src/kiwano/2d/ShapeNode.cpp rename to src/kiwano/2d/ShapeActor.cpp index 556d87de..068de12e 100644 --- a/src/kiwano/2d/ShapeNode.cpp +++ b/src/kiwano/2d/ShapeActor.cpp @@ -18,12 +18,12 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include "ShapeNode.h" +#include "ShapeActor.h" #include "../base/logs.h" namespace kiwano { - ShapeNode::ShapeNode() + ShapeActor::ShapeActor() : fill_color_(Color::White) , stroke_color_(Color(Color::Black, 0)) , stroke_width_(1.f) @@ -31,17 +31,17 @@ namespace kiwano { } - ShapeNode::ShapeNode(ComPtr geometry) - : ShapeNode() + ShapeActor::ShapeActor(ComPtr geometry) + : ShapeActor() { SetGeometry(geometry); } - ShapeNode::~ShapeNode() + ShapeActor::~ShapeActor() { } - Rect ShapeNode::GetBoundingBox() + Rect ShapeActor::GetBoundingBox() { if (!geo_) return Rect{}; @@ -52,7 +52,7 @@ namespace kiwano return Rect{ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top }; } - float ShapeNode::GetLength() + float ShapeActor::GetLength() { float length = 0.f; if (geo_) @@ -63,7 +63,7 @@ namespace kiwano return length; } - bool ShapeNode::ComputePointAtLength(float length, Point& point, Vec2& tangent) + bool ShapeActor::ComputePointAtLength(float length, Point& point, Vec2& tangent) { if (geo_) { @@ -79,7 +79,7 @@ namespace kiwano return false; } - float ShapeNode::ComputeArea() + float ShapeActor::ComputeArea() { if (!geo_) return 0.f; @@ -90,7 +90,7 @@ namespace kiwano return area; } - bool ShapeNode::ContainsPoint(Point const& point) + bool ShapeActor::ContainsPoint(Point const& point) { if (!geo_) return false; @@ -105,27 +105,27 @@ namespace kiwano return !!ret; } - void ShapeNode::SetFillColor(const Color & color) + void ShapeActor::SetFillColor(const Color & color) { fill_color_ = color; } - void ShapeNode::SetStrokeColor(const Color & color) + void ShapeActor::SetStrokeColor(const Color & color) { stroke_color_ = color; } - void ShapeNode::SetStrokeWidth(float width) + void ShapeActor::SetStrokeWidth(float width) { stroke_width_ = std::max(width, 0.f); } - void ShapeNode::SetOutlineJoinStyle(StrokeStyle outline_join) + void ShapeActor::SetOutlineJoinStyle(StrokeStyle outline_join) { outline_join_ = outline_join; } - void ShapeNode::OnRender() + void ShapeActor::OnRender() { if (geo_) { @@ -144,23 +144,23 @@ namespace kiwano } //------------------------------------------------------- - // LineNode + // LineActor //------------------------------------------------------- - LineNode::LineNode() + LineActor::LineActor() { } - LineNode::LineNode(Point const& begin, Point const& end) + LineActor::LineActor(Point const& begin, Point const& end) { SetLine(begin, end); } - LineNode::~LineNode() + LineActor::~LineActor() { } - void LineNode::SetLine(Point const& begin, Point const& end) + void LineActor::SetLine(Point const& begin, Point const& end) { ComPtr path_geo; ComPtr path_sink; @@ -186,40 +186,40 @@ namespace kiwano } } - void LineNode::SetBegin(Point const& begin) + void LineActor::SetBegin(Point const& begin) { SetLine(begin, end_); } - void LineNode::SetEnd(Point const& end) + void LineActor::SetEnd(Point const& end) { SetLine(begin_, end); } //------------------------------------------------------- - // RectNode + // RectActor //------------------------------------------------------- - RectNode::RectNode() + RectActor::RectActor() { } - RectNode::RectNode(Rect const& rect) + RectActor::RectActor(Rect const& rect) { SetRect(rect); } - RectNode::RectNode(Point const& left_top, Size const& size) + RectActor::RectActor(Point const& left_top, Size const& size) { SetRect(Rect{ left_top, size }); } - RectNode::~RectNode() + RectActor::~RectActor() { } - void RectNode::SetRect(Rect const& rect) + void RectActor::SetRect(Rect const& rect) { ComPtr geo; auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); @@ -233,35 +233,35 @@ namespace kiwano //------------------------------------------------------- - // RoundedRectNode + // RoundRectActor //------------------------------------------------------- - RoundedRectNode::RoundedRectNode() + RoundRectActor::RoundRectActor() : radius_x_(0.f) , radius_y_(0.f) { } - RoundedRectNode::RoundedRectNode(Rect const& rect, float radius_x, float radius_y) + RoundRectActor::RoundRectActor(Rect const& rect, float radius_x, float radius_y) { SetRoundedRect(rect, radius_x, radius_y); } - RoundedRectNode::~RoundedRectNode() + RoundRectActor::~RoundRectActor() { } - void RoundedRectNode::SetRadius(float radius_x, float radius_y) + void RoundRectActor::SetRadius(float radius_x, float radius_y) { SetRoundedRect(rect_, radius_x, radius_y); } - void RoundedRectNode::SetRect(Rect const& rect) + void RoundRectActor::SetRect(Rect const& rect) { SetRoundedRect(rect, radius_x_, radius_y_); } - void RoundedRectNode::SetRoundedRect(Rect const& rect, float radius_x, float radius_y) + void RoundRectActor::SetRoundedRect(Rect const& rect, float radius_x, float radius_y) { ComPtr geo; auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); @@ -283,34 +283,34 @@ namespace kiwano //------------------------------------------------------- - // CircleNode + // CircleActor //------------------------------------------------------- - CircleNode::CircleNode() + CircleActor::CircleActor() : radius_(0.f) { } - CircleNode::CircleNode(Point const& center, float radius) + CircleActor::CircleActor(Point const& center, float radius) { SetCircle(center, radius); } - CircleNode::~CircleNode() + CircleActor::~CircleActor() { } - void CircleNode::SetRadius(float radius) + void CircleActor::SetRadius(float radius) { SetCircle(center_, radius); } - void CircleNode::SetCenter(Point const& center) + void CircleActor::SetCenter(Point const& center) { SetCircle(center, radius_); } - void CircleNode::SetCircle(Point const& center, float radius) + void CircleActor::SetCircle(Point const& center, float radius) { ComPtr geo; auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); @@ -330,35 +330,35 @@ namespace kiwano //------------------------------------------------------- - // EllipseNode + // EllipseActor //------------------------------------------------------- - EllipseNode::EllipseNode() + EllipseActor::EllipseActor() : radius_x_(0.f) , radius_y_(0.f) { } - EllipseNode::EllipseNode(Point const& center, float radius_x, float radius_y) + EllipseActor::EllipseActor(Point const& center, float radius_x, float radius_y) { SetEllipse(center, radius_x, radius_y); } - EllipseNode::~EllipseNode() + EllipseActor::~EllipseActor() { } - void EllipseNode::SetRadius(float radius_x, float radius_y) + void EllipseActor::SetRadius(float radius_x, float radius_y) { SetEllipse(center_, radius_x, radius_y); } - void EllipseNode::SetCenter(Point const& center) + void EllipseActor::SetCenter(Point const& center) { SetEllipse(center, radius_x_, radius_y_); } - void EllipseNode::SetEllipse(Point const& center, float radius_x, float radius_y) + void EllipseActor::SetEllipse(Point const& center, float radius_x, float radius_y) { ComPtr geo; auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); @@ -378,18 +378,18 @@ namespace kiwano //------------------------------------------------------- - // PathNode + // PathActor //------------------------------------------------------- - PathNode::PathNode() + PathActor::PathActor() { } - PathNode::~PathNode() + PathActor::~PathActor() { } - void PathNode::BeginPath(Point const& begin_pos) + void PathActor::BeginPath(Point const& begin_pos) { current_geometry_ = nullptr; @@ -406,7 +406,7 @@ namespace kiwano current_sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); } - void PathNode::EndPath(bool closed) + void PathActor::EndPath(bool closed) { if (current_sink_) { @@ -422,13 +422,13 @@ namespace kiwano } } - void PathNode::AddLine(Point const& point) + void PathActor::AddLine(Point const& point) { if (current_sink_) current_sink_->AddLine(DX::ConvertToPoint2F(point)); } - void PathNode::AddLines(Vector const& points) + void PathActor::AddLines(Vector const& points) { if (current_sink_ && !points.empty()) { @@ -439,7 +439,7 @@ namespace kiwano } } - void PathNode::AddBezier(Point const& point1, Point const& point2, Point const& point3) + void PathActor::AddBezier(Point const& point1, Point const& point2, Point const& point3) { if (current_sink_) { @@ -453,7 +453,7 @@ namespace kiwano } } - void PathNode::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) + void PathActor::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) { if (current_sink_) { @@ -469,7 +469,7 @@ namespace kiwano } } - void PathNode::ClearPath() + void PathActor::ClearPath() { geo_ = nullptr; current_sink_ = nullptr; diff --git a/src/kiwano/2d/ShapeNode.h b/src/kiwano/2d/ShapeActor.h similarity index 88% rename from src/kiwano/2d/ShapeNode.h rename to src/kiwano/2d/ShapeActor.h index 2ca42bae..cc7d450c 100644 --- a/src/kiwano/2d/ShapeNode.h +++ b/src/kiwano/2d/ShapeActor.h @@ -25,17 +25,17 @@ namespace kiwano { // 二维图形角色 - class KGE_API ShapeNode + class KGE_API ShapeActor : public VisualActor { public: - ShapeNode(); + ShapeActor(); - ShapeNode( + ShapeActor( ComPtr geometry ); - virtual ~ShapeNode(); + virtual ~ShapeActor(); // 获取填充颜色 Color GetFillColor() const { return fill_color_; } @@ -108,18 +108,18 @@ namespace kiwano // 直线 - class KGE_API LineNode - : public ShapeNode + class KGE_API LineActor + : public ShapeActor { public: - LineNode(); + LineActor(); - LineNode( + LineActor( Point const& begin, Point const& end ); - virtual ~LineNode(); + virtual ~LineActor(); Point const& GetBegin() const { return begin_; } @@ -145,22 +145,22 @@ namespace kiwano // 矩形角色 - class KGE_API RectNode - : public ShapeNode + class KGE_API RectActor + : public ShapeActor { public: - RectNode(); + RectActor(); - RectNode( + RectActor( Rect const& rect ); - RectNode( + RectActor( Point const& left_top, Size const& size ); - virtual ~RectNode(); + virtual ~RectActor(); Rect const& GetRect() const { return rect_; } @@ -172,19 +172,19 @@ namespace kiwano // 圆角矩形角色 - class KGE_API RoundedRectNode - : public ShapeNode + class KGE_API RoundRectActor + : public ShapeActor { public: - RoundedRectNode(); + RoundRectActor(); - RoundedRectNode( + RoundRectActor( Rect const& rect, float radius_x, float radius_y ); - virtual ~RoundedRectNode(); + virtual ~RoundRectActor(); float GetRadiusX() const { return radius_x_; } @@ -215,18 +215,18 @@ namespace kiwano // 圆形角色 - class KGE_API CircleNode - : public ShapeNode + class KGE_API CircleActor + : public ShapeActor { public: - CircleNode(); + CircleActor(); - CircleNode( + CircleActor( Point const& center, float radius ); - virtual ~CircleNode(); + virtual ~CircleActor(); float GetRadius() const { return radius_; } @@ -252,19 +252,19 @@ namespace kiwano // 椭圆角色 - class KGE_API EllipseNode - : public ShapeNode + class KGE_API EllipseActor + : public ShapeActor { public: - EllipseNode(); + EllipseActor(); - EllipseNode( + EllipseActor( Point const& center, float radius_x, float radius_y ); - virtual ~EllipseNode(); + virtual ~EllipseActor(); float GetRadiusX() const { return radius_x_; } @@ -295,13 +295,13 @@ namespace kiwano // 路径角色 - class KGE_API PathNode - : public ShapeNode + class KGE_API PathActor + : public ShapeActor { public: - PathNode(); + PathActor(); - virtual ~PathNode(); + virtual ~PathActor(); // 开始添加路径 void BeginPath( diff --git a/src/kiwano/2d/include-forwards.h b/src/kiwano/2d/include-forwards.h index f2c480d7..35f39f36 100644 --- a/src/kiwano/2d/include-forwards.h +++ b/src/kiwano/2d/include-forwards.h @@ -41,13 +41,13 @@ namespace kiwano KGE_DECLARE_SMART_PTR(GifSprite); KGE_DECLARE_SMART_PTR(Text); KGE_DECLARE_SMART_PTR(Canvas); - KGE_DECLARE_SMART_PTR(ShapeNode); - KGE_DECLARE_SMART_PTR(LineNode); - KGE_DECLARE_SMART_PTR(RectNode); - KGE_DECLARE_SMART_PTR(RoundedRectNode); - KGE_DECLARE_SMART_PTR(CircleNode); - KGE_DECLARE_SMART_PTR(EllipseNode); - KGE_DECLARE_SMART_PTR(PathNode); + KGE_DECLARE_SMART_PTR(ShapeActor); + KGE_DECLARE_SMART_PTR(LineActor); + KGE_DECLARE_SMART_PTR(RectActor); + KGE_DECLARE_SMART_PTR(RoundRectActor); + KGE_DECLARE_SMART_PTR(CircleActor); + KGE_DECLARE_SMART_PTR(EllipseActor); + KGE_DECLARE_SMART_PTR(PathActor); KGE_DECLARE_SMART_PTR(Action); KGE_DECLARE_SMART_PTR(ActionTween); diff --git a/src/kiwano/base/Director.cpp b/src/kiwano/base/Director.cpp index c318438e..50b4ac45 100644 --- a/src/kiwano/base/Director.cpp +++ b/src/kiwano/base/Director.cpp @@ -22,7 +22,7 @@ #include "../2d/Actor.h" #include "../2d/Stage.h" #include "../2d/Transition.h" -#include "../2d/DebugNode.h" +#include "../2d/DebugActor.h" namespace kiwano { diff --git a/src/kiwano/kiwano.h b/src/kiwano/kiwano.h index 7607a2ae..6a2d0c7a 100644 --- a/src/kiwano/kiwano.h +++ b/src/kiwano/kiwano.h @@ -105,8 +105,8 @@ #include "2d/GifSprite.h" #include "2d/Text.h" #include "2d/Canvas.h" -#include "2d/ShapeNode.h" -#include "2d/DebugNode.h" +#include "2d/ShapeActor.h" +#include "2d/DebugActor.h" #include "platform/modules.h" #include "platform/Application.h" From 47be1dc413cfbeed88974665aed3b160a4b02ffd Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Wed, 14 Aug 2019 00:28:25 +0800 Subject: [PATCH 05/11] add Renderer::CheckVisibility() --- src/kiwano-imgui/src/ImGuiLayer.cpp | 3 ++- src/kiwano-imgui/src/ImGuiLayer.h | 2 +- src/kiwano/2d/Actor.cpp | 26 +++++++++++-------------- src/kiwano/2d/Actor.h | 30 ++++++++++------------------- src/kiwano/2d/Canvas.cpp | 6 ++++-- src/kiwano/2d/Canvas.h | 4 ++-- src/kiwano/2d/DebugActor.cpp | 10 +++++----- src/kiwano/2d/DebugActor.h | 10 +++++----- src/kiwano/2d/GifSprite.cpp | 10 ++++++---- src/kiwano/2d/GifSprite.h | 4 ++-- src/kiwano/2d/ShapeActor.cpp | 21 ++++++++++++++++---- src/kiwano/2d/ShapeActor.h | 9 ++++++--- src/kiwano/2d/Sprite.cpp | 7 ++++--- src/kiwano/2d/Sprite.h | 4 ++-- src/kiwano/2d/Text.cpp | 8 ++++---- src/kiwano/2d/Text.h | 6 +++--- src/kiwano/2d/Transition.cpp | 8 +++----- src/kiwano/2d/Transition.h | 3 ++- src/kiwano/base/Component.h | 4 +++- src/kiwano/base/Director.cpp | 12 +++++++----- src/kiwano/base/Director.h | 2 +- src/kiwano/platform/Application.cpp | 3 ++- src/kiwano/renderer/render.cpp | 7 +++++++ src/kiwano/renderer/render.h | 5 +++++ 24 files changed, 114 insertions(+), 90 deletions(-) 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; From 90bfda923d357498c45ab614b6657f20827f6383 Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Wed, 14 Aug 2019 08:52:01 +0800 Subject: [PATCH 06/11] minor fixes --- src/kiwano/2d/Transition.cpp | 8 +- src/kiwano/renderer/render.cpp | 501 +++++++++++++++++++++------------ src/kiwano/renderer/render.h | 47 ++-- 3 files changed, 340 insertions(+), 216 deletions(-) diff --git a/src/kiwano/2d/Transition.cpp b/src/kiwano/2d/Transition.cpp index 2693bad5..b17b98c3 100644 --- a/src/kiwano/2d/Transition.cpp +++ b/src/kiwano/2d/Transition.cpp @@ -65,16 +65,12 @@ namespace kiwano if (in_scene_) { - ThrowIfFailed( - Renderer::GetInstance()->CreateLayer(in_layer_) - ); + Renderer::GetInstance()->CreateLayer(in_layer_); } if (out_scene_) { - ThrowIfFailed( - Renderer::GetInstance()->CreateLayer(out_layer_) - ); + Renderer::GetInstance()->CreateLayer(out_layer_); } window_size_ = Renderer::GetInstance()->GetOutputSize(); diff --git a/src/kiwano/renderer/render.cpp b/src/kiwano/renderer/render.cpp index 5867d3a9..984855d3 100644 --- a/src/kiwano/renderer/render.cpp +++ b/src/kiwano/renderer/render.cpp @@ -211,115 +211,172 @@ namespace kiwano return hr; } - HRESULT Renderer::CreateLayer(ComPtr& layer) + void Renderer::IncreasePrimitivesCount() { - if (!device_context_) - return E_UNEXPECTED; - - layer = nullptr; - return device_context_->CreateLayer(&layer); + if (collecting_status_) + { + ++status_.primitives; + } } - HRESULT Renderer::DrawGeometry( + void Renderer::CreateLayer(ComPtr& layer) + { + HRESULT hr = S_OK; + ComPtr new_layer; + + if (!device_context_) + { + hr = E_UNEXPECTED; + } + + if (SUCCEEDED(hr)) + { + hr = device_context_->CreateLayer(&new_layer); + } + + if (SUCCEEDED(hr)) + { + layer = new_layer; + } + + ThrowIfFailed(hr); + } + + void Renderer::DrawGeometry( ComPtr const& geometry, Color const& stroke_color, float stroke_width, StrokeStyle stroke ) { + HRESULT hr = S_OK; if (!solid_color_brush_ || !device_context_) - return E_UNEXPECTED; + { + hr = E_UNEXPECTED; + } - solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color)); + if (SUCCEEDED(hr)) + { + solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color)); - device_context_->DrawGeometry( - geometry.get(), - solid_color_brush_.get(), - stroke_width, - d2d_res_->GetStrokeStyle(stroke) - ); + device_context_->DrawGeometry( + geometry.get(), + solid_color_brush_.get(), + stroke_width, + d2d_res_->GetStrokeStyle(stroke) + ); - if (collecting_status_) - ++status_.primitives; - return S_OK; + IncreasePrimitivesCount(); + } + + ThrowIfFailed(hr); } - HRESULT Renderer::FillGeometry(ComPtr const & geometry, Color const& fill_color) + void Renderer::FillGeometry(ComPtr const & geometry, Color const& fill_color) { + HRESULT hr = S_OK; if (!solid_color_brush_ || !device_context_) - return E_UNEXPECTED; + { + hr = E_UNEXPECTED; + } - solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color)); - device_context_->FillGeometry( - geometry.get(), - solid_color_brush_.get() - ); + if (SUCCEEDED(hr)) + { + solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color)); + device_context_->FillGeometry( + geometry.get(), + solid_color_brush_.get() + ); + } - return S_OK; + ThrowIfFailed(hr); } - HRESULT Renderer::DrawRectangle(Rect const& rect, const Color& stroke_color, float stroke_width, StrokeStyle stroke) + void Renderer::DrawRectangle(Rect const& rect, const Color& stroke_color, float stroke_width, StrokeStyle stroke) { + HRESULT hr = S_OK; if (!solid_color_brush_ || !device_context_) - return E_UNEXPECTED; + { + hr = E_UNEXPECTED; + } - solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color)); + if (SUCCEEDED(hr)) + { + solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color)); - device_context_->DrawRectangle( - DX::ConvertToRectF(rect), - solid_color_brush_.get(), - stroke_width, - d2d_res_->GetStrokeStyle(stroke) - ); + device_context_->DrawRectangle( + DX::ConvertToRectF(rect), + solid_color_brush_.get(), + stroke_width, + d2d_res_->GetStrokeStyle(stroke) + ); - if (collecting_status_) - ++status_.primitives; - return S_OK; + IncreasePrimitivesCount(); + } + + ThrowIfFailed(hr); } - HRESULT Renderer::FillRectangle(Rect const& rect, Color const& fill_color) + void Renderer::FillRectangle(Rect const& rect, Color const& fill_color) { + HRESULT hr = S_OK; if (!solid_color_brush_ || !device_context_) - return E_UNEXPECTED; + { + hr = E_UNEXPECTED; + } - solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color)); - device_context_->FillRectangle( - DX::ConvertToRectF(rect), - solid_color_brush_.get() - ); + if (SUCCEEDED(hr)) + { + solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color)); + device_context_->FillRectangle( + DX::ConvertToRectF(rect), + solid_color_brush_.get() + ); + } - return S_OK; + ThrowIfFailed(hr); } - HRESULT Renderer::DrawBitmap(ComPtr const & bitmap, Rect const& src_rect, Rect const& dest_rect) + void Renderer::DrawBitmap(ComPtr const & bitmap, Rect const& src_rect, Rect const& dest_rect) { + HRESULT hr = S_OK; if (!device_context_) - return E_UNEXPECTED; + { + hr = E_UNEXPECTED; + } - if (!bitmap) - return S_OK; + if (SUCCEEDED(hr) && bitmap) + { + device_context_->DrawBitmap( + bitmap.get(), + DX::ConvertToRectF(dest_rect), + opacity_, + D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, + DX::ConvertToRectF(src_rect) + ); - device_context_->DrawBitmap( - bitmap.get(), - DX::ConvertToRectF(dest_rect), - opacity_, - D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, - DX::ConvertToRectF(src_rect) - ); + IncreasePrimitivesCount(); + } - if (collecting_status_) - ++status_.primitives; - return S_OK; + ThrowIfFailed(hr); } - HRESULT Renderer::DrawTextLayout(ComPtr const& text_layout) + void Renderer::DrawTextLayout(ComPtr const& text_layout) { + HRESULT hr = S_OK; if (!text_renderer_) - return E_UNEXPECTED; + { + hr = E_UNEXPECTED; + } - if (collecting_status_) - ++status_.primitives; - return text_layout->Draw(nullptr, text_renderer_.get(), 0, 0); + if (SUCCEEDED(hr)) + { + hr = text_layout->Draw(nullptr, text_renderer_.get(), 0, 0); + + IncreasePrimitivesCount(); + } + + ThrowIfFailed(hr); } void Renderer::SetVSyncEnabled(bool enabled) @@ -327,66 +384,101 @@ namespace kiwano vsync_ = enabled; } - HRESULT Renderer::PushClip(const Matrix & clip_matrix, const Size & clip_size) + void Renderer::PushClip(const Matrix & clip_matrix, const Size & clip_size) { + HRESULT hr = S_OK; if (!device_context_) - return E_UNEXPECTED; - - device_context_->SetTransform(DX::ConvertToMatrix3x2F(clip_matrix)); - device_context_->PushAxisAlignedClip( - D2D1::RectF(0, 0, clip_size.x, clip_size.y), - D2D1_ANTIALIAS_MODE_PER_PRIMITIVE - ); - return S_OK; - } - - HRESULT Renderer::PopClip() - { - if (!device_context_) - return E_UNEXPECTED; - - device_context_->PopAxisAlignedClip(); - return S_OK; - } - - HRESULT Renderer::PushLayer(ComPtr const& layer, LayerProperties const& properties) - { - if (!device_context_ || !solid_color_brush_) - return E_UNEXPECTED; - - device_context_->PushLayer( - D2D1::LayerParameters( - DX::ConvertToRectF(properties.area), - nullptr, - D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, - D2D1::Matrix3x2F::Identity(), - properties.opacity, - solid_color_brush_.get(), - D2D1_LAYER_OPTIONS_NONE - ), - layer.get() - ); - return S_OK; - } - - HRESULT Renderer::PopLayer() - { - if (!device_context_) - return E_UNEXPECTED; - - device_context_->PopLayer(); - return S_OK; - } - - HRESULT Renderer::Resize(UINT width, UINT height) - { - output_size_.x = static_cast(width); - output_size_.y = static_cast(height); - if (d3d_res_) { - return d3d_res_->SetLogicalSize(output_size_); + hr = E_UNEXPECTED; } - return S_OK; + + if (SUCCEEDED(hr)) + { + device_context_->SetTransform(DX::ConvertToMatrix3x2F(clip_matrix)); + device_context_->PushAxisAlignedClip( + D2D1::RectF(0, 0, clip_size.x, clip_size.y), + D2D1_ANTIALIAS_MODE_PER_PRIMITIVE + ); + } + + ThrowIfFailed(hr); + } + + void Renderer::PopClip() + { + HRESULT hr = S_OK; + if (!device_context_) + { + hr = E_UNEXPECTED; + } + + if (SUCCEEDED(hr)) + { + device_context_->PopAxisAlignedClip(); + } + + ThrowIfFailed(hr); + } + + void Renderer::PushLayer(ComPtr const& layer, LayerProperties const& properties) + { + HRESULT hr = S_OK; + if (!device_context_ || !solid_color_brush_) + { + hr = E_UNEXPECTED; + } + + if (SUCCEEDED(hr)) + { + device_context_->PushLayer( + D2D1::LayerParameters( + DX::ConvertToRectF(properties.area), + nullptr, + D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, + D2D1::Matrix3x2F::Identity(), + properties.opacity, + solid_color_brush_.get(), + D2D1_LAYER_OPTIONS_NONE + ), + layer.get() + ); + } + + ThrowIfFailed(hr); + } + + void Renderer::PopLayer() + { + HRESULT hr = S_OK; + if (!device_context_) + { + hr = E_UNEXPECTED; + } + + if (SUCCEEDED(hr)) + { + device_context_->PopLayer(); + } + + ThrowIfFailed(hr); + } + + void Renderer::Resize(UINT width, UINT height) + { + HRESULT hr = S_OK; + if (!d3d_res_) + { + hr = E_UNEXPECTED; + } + + if (SUCCEEDED(hr)) + { + output_size_.x = static_cast(width); + output_size_.y = static_cast(height); + hr = d3d_res_->SetLogicalSize(output_size_); + } + + ThrowIfFailed(hr); } void Renderer::SetCollectingStatus(bool collecting) @@ -399,29 +491,43 @@ namespace kiwano clear_color_ = color; } - HRESULT Renderer::SetTransform(const Matrix & matrix) + void Renderer::SetTransform(const Matrix & matrix) { + HRESULT hr = S_OK; if (!device_context_) - return E_UNEXPECTED; - - device_context_->SetTransform(DX::ConvertToMatrix3x2F(&matrix)); - return S_OK; - } - - HRESULT Renderer::SetOpacity(float opacity) - { - if (!solid_color_brush_) - return E_UNEXPECTED; - - if (opacity_ != opacity) { - opacity_ = opacity; - solid_color_brush_->SetOpacity(opacity); + hr = E_UNEXPECTED; } - return S_OK; + + if (SUCCEEDED(hr)) + { + device_context_->SetTransform(DX::ConvertToMatrix3x2F(&matrix)); + } + + ThrowIfFailed(hr); } - HRESULT Renderer::SetTextStyle( + void Renderer::SetOpacity(float opacity) + { + HRESULT hr = S_OK; + if (!solid_color_brush_) + { + hr = E_UNEXPECTED; + } + + if (SUCCEEDED(hr)) + { + if (opacity_ != opacity) + { + opacity_ = opacity; + solid_color_brush_->SetOpacity(opacity); + } + } + + ThrowIfFailed(hr); + } + + void Renderer::SetTextStyle( float opacity, Color const& color, bool has_outline, @@ -430,58 +536,79 @@ namespace kiwano StrokeStyle outline_stroke ) { + HRESULT hr = S_OK; if (!text_renderer_ || !d3d_res_) - return E_UNEXPECTED; - - text_renderer_->SetTextStyle( - opacity, - DX::ConvertToColorF(color), - has_outline, - DX::ConvertToColorF(outline_color), - outline_width, - d2d_res_->GetStrokeStyle(outline_stroke) - ); - return S_OK; - } - - HRESULT Renderer::SetAntialiasMode(bool enabled) - { - if (!device_context_) - return E_UNEXPECTED; - - device_context_->SetAntialiasMode( - enabled ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED - ); - antialias_ = enabled; - return S_OK; - } - - HRESULT Renderer::SetTextAntialiasMode(TextAntialias mode) - { - if (!device_context_) - return E_UNEXPECTED; - - text_antialias_ = mode; - D2D1_TEXT_ANTIALIAS_MODE antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE; - switch (text_antialias_) { - case TextAntialias::Default: - antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT; - break; - case TextAntialias::ClearType: - antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE; - break; - case TextAntialias::GrayScale: - antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE; - break; - case TextAntialias::None: - antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_ALIASED; - break; - default: - break; + hr = E_UNEXPECTED; } - device_context_->SetTextAntialiasMode(antialias_mode); - return S_OK; + + if (SUCCEEDED(hr)) + { + text_renderer_->SetTextStyle( + opacity, + DX::ConvertToColorF(color), + has_outline, + DX::ConvertToColorF(outline_color), + outline_width, + d2d_res_->GetStrokeStyle(outline_stroke) + ); + } + + ThrowIfFailed(hr); + } + + void Renderer::SetAntialiasMode(bool enabled) + { + HRESULT hr = S_OK; + if (!device_context_) + { + hr = E_UNEXPECTED; + } + + if (SUCCEEDED(hr)) + { + device_context_->SetAntialiasMode( + enabled ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED + ); + antialias_ = enabled; + } + + ThrowIfFailed(hr); + } + + void Renderer::SetTextAntialiasMode(TextAntialias mode) + { + HRESULT hr = S_OK; + if (!device_context_) + { + hr = E_UNEXPECTED; + } + + if (SUCCEEDED(hr)) + { + text_antialias_ = mode; + D2D1_TEXT_ANTIALIAS_MODE antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE; + switch (text_antialias_) + { + case TextAntialias::Default: + antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT; + break; + case TextAntialias::ClearType: + antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE; + break; + case TextAntialias::GrayScale: + antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE; + break; + case TextAntialias::None: + antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_ALIASED; + break; + default: + break; + } + device_context_->SetTextAntialiasMode(antialias_mode); + } + + ThrowIfFailed(hr); } bool Renderer::CheckVisibility(Size const& content_size, Matrix const& transform) diff --git a/src/kiwano/renderer/render.h b/src/kiwano/renderer/render.h index 6b6a3dbe..c796a363 100644 --- a/src/kiwano/renderer/render.h +++ b/src/kiwano/renderer/render.h @@ -52,41 +52,41 @@ namespace kiwano KGE_DECLARE_SINGLETON(Renderer); public: - HRESULT CreateLayer( + void CreateLayer( ComPtr& layer ); - HRESULT DrawGeometry( + void DrawGeometry( ComPtr const& geometry, const Color& stroke_color, float stroke_width, StrokeStyle stroke = StrokeStyle::Miter ); - HRESULT FillGeometry( + void FillGeometry( ComPtr const& geometry, Color const& fill_color ); - HRESULT DrawRectangle( + void DrawRectangle( Rect const& rect, const Color& stroke_color, float stroke_width, StrokeStyle stroke = StrokeStyle::Miter ); - HRESULT FillRectangle( + void FillRectangle( Rect const& rect, Color const& fill_color ); - HRESULT DrawBitmap( + void DrawBitmap( ComPtr const& bitmap, Rect const& src_rect, Rect const& dest_rect ); - HRESULT DrawTextLayout( + void DrawTextLayout( ComPtr const& text_layout ); @@ -96,12 +96,12 @@ namespace kiwano ); // 设置抗锯齿模式 - HRESULT SetAntialiasMode( + void SetAntialiasMode( bool enabled ); // 设置文字抗锯齿模式 - HRESULT SetTextAntialiasMode( + void SetTextAntialiasMode( TextAntialias mode ); @@ -111,15 +111,15 @@ namespace kiwano ); // 设置画笔透明度 - HRESULT SetOpacity( + void SetOpacity( float opacity ); - HRESULT SetTransform( + void SetTransform( const Matrix& matrix ); - HRESULT SetTextStyle( + void SetTextStyle( float opacity, const Color& color, bool has_outline, @@ -128,21 +128,21 @@ namespace kiwano StrokeStyle outline_stroke ); - HRESULT PushClip( + void PushClip( const Matrix& clip_matrix, const Size& clip_size ); - HRESULT PopClip(); + void PopClip(); - HRESULT PushLayer( + void PushLayer( ComPtr const& layer, LayerProperties const& properties ); - HRESULT PopLayer(); + void PopLayer(); - HRESULT Resize( + void Resize( UINT width, UINT height ); @@ -200,13 +200,14 @@ namespace kiwano HRESULT EndDraw(); - private: - HWND hwnd_; - float opacity_; - bool antialias_; - bool vsync_; - bool collecting_status_; + void IncreasePrimitivesCount(); + private: + bool vsync_; + bool antialias_; + bool collecting_status_; + float opacity_; + HWND hwnd_; Size output_size_; Color clear_color_; TextAntialias text_antialias_; From 5327159e9923b0607fed82dee8a6c330e5b65ce9 Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Wed, 14 Aug 2019 09:09:59 +0800 Subject: [PATCH 07/11] update Tween --- src/kiwano/2d/action/ActionHelper.h | 70 +++++++++++++++-------------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/src/kiwano/2d/action/ActionHelper.h b/src/kiwano/2d/action/ActionHelper.h index 57c681b8..4735b1e6 100644 --- a/src/kiwano/2d/action/ActionHelper.h +++ b/src/kiwano/2d/action/ActionHelper.h @@ -83,9 +83,9 @@ namespace kiwano inline TweenHelper& SetName(String const& name) { base->SetName(name); return (*this); } // 获取指针 - inline ActionTweenPtr Get() const { return base; } + inline ActionTweenPtr Get() const { return base; } - inline TweenHelper(ActionTweenPtr base) : base(base) {} + inline TweenHelper(ActionTweenPtr base) : base(base) {} inline operator ActionPtr() const { return base; } @@ -100,115 +100,117 @@ namespace kiwano { public: static inline TweenHelper - MoveBy(Point const& vector) + MoveBy(Duration dur, Point const& vector) { - return TweenHelper(new kiwano::ActionMoveBy(0, vector)); + return TweenHelper(new kiwano::ActionMoveBy(dur, vector)); } static inline TweenHelper - MoveTo(Point const& pos) + MoveTo(Duration dur, Point const& pos) { - return TweenHelper(new kiwano::ActionMoveTo(0, pos)); + return TweenHelper(new kiwano::ActionMoveTo(dur, pos)); } static inline TweenHelper JumpBy( + Duration dur, Point const& pos, /* 目的坐标 */ float height, /* 跳跃高度 */ int jumps = 1) /* 跳跃次数 */ { - return TweenHelper(new kiwano::ActionJumpBy(0, pos, height, jumps)); + return TweenHelper(new kiwano::ActionJumpBy(dur, pos, height, jumps)); } static inline TweenHelper JumpTo( + Duration dur, Point const& pos, /* 目的坐标 */ float height, /* 跳跃高度 */ int jumps = 1) /* 跳跃次数 */ { - return TweenHelper(new kiwano::ActionJumpTo(0, pos, height, jumps)); + return TweenHelper(new kiwano::ActionJumpTo(dur, pos, height, jumps)); } static inline TweenHelper - ScaleBy(float scale) + ScaleBy(Duration dur, float scale) { - return TweenHelper(new kiwano::ActionScaleBy(0, scale)); + return TweenHelper(new kiwano::ActionScaleBy(dur, scale)); } static inline TweenHelper - ScaleBy(float scale_x, float scale_y) + ScaleBy(Duration dur, float scale_x, float scale_y) { - return TweenHelper(new kiwano::ActionScaleBy(0, scale_x, scale_y)); + return TweenHelper(new kiwano::ActionScaleBy(dur, scale_x, scale_y)); } static inline TweenHelper - ScaleTo(float scale) + ScaleTo(Duration dur, float scale) { - return TweenHelper(new kiwano::ActionScaleTo(0, scale)); + return TweenHelper(new kiwano::ActionScaleTo(dur, scale)); } static inline TweenHelper - ScaleTo(float scale_x, float scale_y) + ScaleTo(Duration dur, float scale_x, float scale_y) { - return TweenHelper(new kiwano::ActionScaleTo(0, scale_x, scale_y)); + return TweenHelper(new kiwano::ActionScaleTo(dur, scale_x, scale_y)); } static inline TweenHelper - FadeTo(float opacity) + FadeTo(Duration dur, float opacity) { - return TweenHelper(new kiwano::ActionFadeTo(0, opacity)); + return TweenHelper(new kiwano::ActionFadeTo(dur, opacity)); } static inline TweenHelper - FadeIn(Duration dur) + FadeIn(Duration dur) { return TweenHelper(new kiwano::ActionFadeIn(dur)); } static inline TweenHelper - FadeOut(Duration dur) + FadeOut(Duration dur) { return TweenHelper(new kiwano::ActionFadeOut(dur)); } static inline TweenHelper - RotateBy(float rotation) + RotateBy(Duration dur, float rotation) { - return TweenHelper(new kiwano::ActionRotateBy(0, rotation)); + return TweenHelper(new kiwano::ActionRotateBy(dur, rotation)); } static inline TweenHelper - RotateTo(float rotation) + RotateTo(Duration dur, float rotation) { - return TweenHelper(new kiwano::ActionRotateTo(0, rotation)); + return TweenHelper(new kiwano::ActionRotateTo(dur, rotation)); } static inline TweenHelper - Animation(FrameSequencePtr frames) + Animation(Duration dur, FrameSequencePtr frames) { - return TweenHelper(new kiwano::Animation(0, frames)); + return TweenHelper(new kiwano::Animation(dur, frames)); } static inline TweenHelper - Custom(kiwano::ActionCustom::TweenFunc tween_func) + Custom(Duration dur, ActionCustom::TweenFunc tween_func) { - return TweenHelper(new kiwano::ActionCustom(0, tween_func)); + return TweenHelper(new kiwano::ActionCustom(dur, tween_func)); } static inline ActionHelper - Delay(Duration delay) + Delay(Duration delay) { return ActionHelper(new kiwano::ActionDelay(delay)); } static inline ActionHelper - Group(Vector const& actions, bool sequence = true) + Group(Vector const& actions, bool sequence = true) { return ActionHelper(new kiwano::ActionGroup(actions, sequence)); } static inline ActionHelper - Multiple(Vector const& actions) + Multiple(Vector const& actions) { return ActionHelper(new kiwano::ActionGroup(actions, false)); } @@ -226,14 +228,14 @@ namespace kiwano KGE_DEPRECATED("Tween::OpacityTo is deprecated, use Tween::FadeTo instead") static inline TweenHelper - OpacityTo(float opacity) + OpacityTo(Duration dur, float opacity) { - return TweenHelper(new kiwano::ActionFadeTo(0, opacity)); + return TweenHelper(new kiwano::ActionFadeTo(dur, opacity)); } KGE_DEPRECATED("Tween::Sequence is deprecated, use Tween::Group instead") static inline ActionHelper - Sequence(Vector const& actions) + Sequence(Vector const& actions) { return ActionHelper(new kiwano::ActionGroup(actions, true)); } From 671719fb34a7ed3aee4d6af57dfed23b298bcb5b Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Wed, 14 Aug 2019 21:38:37 +0800 Subject: [PATCH 08/11] Add Geometry && add GeometrySink && rename ActionPath to ActionWalk --- projects/kiwano.vcxproj | 6 + projects/kiwano.vcxproj.filters | 18 ++ src/kiwano/2d/ShapeActor.cpp | 282 +++++---------------------- src/kiwano/2d/ShapeActor.h | 147 ++++---------- src/kiwano/2d/Sprite.cpp | 1 + src/kiwano/2d/action/ActionDelay.cpp | 40 ++++ src/kiwano/2d/action/ActionDelay.h | 41 ++++ src/kiwano/2d/action/ActionHelper.h | 34 +++- src/kiwano/2d/action/ActionTween.cpp | 232 ---------------------- src/kiwano/2d/action/ActionTween.h | 102 ---------- src/kiwano/2d/action/ActionWalk.cpp | 128 ++++++++++++ src/kiwano/2d/action/ActionWalk.h | 112 +++++++++++ src/kiwano/2d/include-forwards.h | 2 +- src/kiwano/kiwano.h | 2 + src/kiwano/renderer/Geometry.cpp | 203 +++++++++++++++++++ src/kiwano/renderer/Geometry.h | 126 ++++++++++++ src/kiwano/renderer/Image.h | 2 +- src/kiwano/renderer/render.cpp | 155 ++++++++++++++- src/kiwano/renderer/render.h | 35 +++- 19 files changed, 968 insertions(+), 700 deletions(-) create mode 100644 src/kiwano/2d/action/ActionDelay.cpp create mode 100644 src/kiwano/2d/action/ActionDelay.h create mode 100644 src/kiwano/2d/action/ActionWalk.cpp create mode 100644 src/kiwano/2d/action/ActionWalk.h create mode 100644 src/kiwano/renderer/Geometry.cpp create mode 100644 src/kiwano/renderer/Geometry.h diff --git a/projects/kiwano.vcxproj b/projects/kiwano.vcxproj index 545fbfad..6ae1c33b 100644 --- a/projects/kiwano.vcxproj +++ b/projects/kiwano.vcxproj @@ -2,9 +2,11 @@ + + @@ -69,6 +71,7 @@ + @@ -86,8 +89,10 @@ + + @@ -120,6 +125,7 @@ + diff --git a/projects/kiwano.vcxproj.filters b/projects/kiwano.vcxproj.filters index 47f84249..f70612b5 100644 --- a/projects/kiwano.vcxproj.filters +++ b/projects/kiwano.vcxproj.filters @@ -279,6 +279,15 @@ 2d + + renderer + + + 2d\action + + + 2d\action + @@ -425,5 +434,14 @@ 2d + + renderer + + + 2d\action + + + 2d\action + \ No newline at end of file diff --git a/src/kiwano/2d/ShapeActor.cpp b/src/kiwano/2d/ShapeActor.cpp index 8939ebda..1e4689b5 100644 --- a/src/kiwano/2d/ShapeActor.cpp +++ b/src/kiwano/2d/ShapeActor.cpp @@ -20,6 +20,7 @@ #include "ShapeActor.h" #include "../base/logs.h" +#include "../renderer/render.h" namespace kiwano { @@ -31,7 +32,7 @@ namespace kiwano { } - ShapeActor::ShapeActor(ComPtr geometry) + ShapeActor::ShapeActor(Geometry geometry) : ShapeActor() { SetGeometry(geometry); @@ -46,10 +47,7 @@ namespace kiwano if (!geo_) return Rect{}; - D2D1_RECT_F rect; - // no matter it failed or not - geo_->GetBounds(D2D1::Matrix3x2F::Identity(), &rect); - return Rect{ rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top }; + return geo_.GetBoundingBox(Matrix()); } Rect ShapeActor::GetBoundingBox() const @@ -57,63 +55,7 @@ namespace kiwano 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; - if (geo_) - { - // no matter it failed or not - geo_->ComputeLength(D2D1::Matrix3x2F::Identity(), &length); - } - return length; - } - - bool ShapeActor::ComputePointAtLength(float length, Point& point, Vec2& tangent) - { - if (geo_) - { - if (SUCCEEDED(geo_->ComputePointAtLength( - length, - D2D1::Matrix3x2F::Identity(), - DX::ConvertToPoint2F(&point), - DX::ConvertToPoint2F(&tangent)))) - { - return true; - } - } - return false; - } - - float ShapeActor::ComputeArea() - { - if (!geo_) - return 0.f; - - float area = 0.f; - // no matter it failed or not - geo_->ComputeArea(D2D1::Matrix3x2F::Identity(), &area); - return area; - } - - bool ShapeActor::ContainsPoint(Point const& point) - { - if (!geo_) - return false; - - BOOL ret = 0; - // no matter it failed or not - geo_->FillContainsPoint( - DX::ConvertToPoint2F(point), - D2D1::Matrix3x2F::Identity(), - &ret - ); - return !!ret; + return geo_.GetBoundingBox(GetTransformMatrix()); } void ShapeActor::SetFillColor(const Color & color) @@ -164,49 +106,23 @@ namespace kiwano { } - LineActor::LineActor(Point const& begin, Point const& end) + LineActor::LineActor(Point const& end) { - SetLine(begin, end); + SetEndPoint(end); } LineActor::~LineActor() { } - void LineActor::SetLine(Point const& begin, Point const& end) + void LineActor::SetEndPoint(Point const& end) { - ComPtr path_geo; - ComPtr path_sink; + Renderer::GetInstance()->CreateLineGeometry(geo_, Point{}, end); - HRESULT hr = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory()->CreatePathGeometry(&path_geo); - - if (SUCCEEDED(hr)) + if (geo_) { - hr = path_geo->Open(&path_sink); + SetSize(end); } - - if (SUCCEEDED(hr)) - { - path_sink->BeginFigure(DX::ConvertToPoint2F(begin), D2D1_FIGURE_BEGIN_FILLED); - path_sink->AddLine(DX::ConvertToPoint2F(end)); - path_sink->EndFigure(D2D1_FIGURE_END_OPEN); - hr = path_sink->Close(); - } - - if (SUCCEEDED(hr)) - { - geo_ = path_geo; - } - } - - void LineActor::SetBegin(Point const& begin) - { - SetLine(begin, end_); - } - - void LineActor::SetEnd(Point const& end) - { - SetLine(begin_, end); } @@ -218,29 +134,22 @@ namespace kiwano { } - RectActor::RectActor(Rect const& rect) + RectActor::RectActor(Size const& size) { - SetRect(rect); - } - - RectActor::RectActor(Point const& left_top, Size const& size) - { - SetRect(Rect{ left_top, size }); + SetRectSize(size); } RectActor::~RectActor() { } - void RectActor::SetRect(Rect const& rect) + void RectActor::SetRectSize(Size const& size) { - ComPtr geo; - auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); + Renderer::GetInstance()->CreateRectGeometry(geo_, Rect{ Point{}, size }); - if (SUCCEEDED(factory->CreateRectangleGeometry(DX::ConvertToRectF(rect), &geo))) + if (geo_) { - geo_ = geo; - rect_ = rect; + SetSize(size); } } @@ -250,47 +159,35 @@ namespace kiwano //------------------------------------------------------- RoundRectActor::RoundRectActor() - : radius_x_(0.f) - , radius_y_(0.f) { } - RoundRectActor::RoundRectActor(Rect const& rect, float radius_x, float radius_y) + RoundRectActor::RoundRectActor(Size const& size, Vec2 const& radius) { - SetRoundedRect(rect, radius_x, radius_y); + SetRoundedRect(size, radius); } RoundRectActor::~RoundRectActor() { } - void RoundRectActor::SetRadius(float radius_x, float radius_y) + void RoundRectActor::SetRadius(Vec2 const& radius) { - SetRoundedRect(rect_, radius_x, radius_y); + SetRoundedRect(size_, radius); } - void RoundRectActor::SetRect(Rect const& rect) + void RoundRectActor::SetRectSize(Size const& size) { - SetRoundedRect(rect, radius_x_, radius_y_); + SetRoundedRect(size, radius_); } - void RoundRectActor::SetRoundedRect(Rect const& rect, float radius_x, float radius_y) + void RoundRectActor::SetRoundedRect(Size const& size, Vec2 const& radius) { - ComPtr geo; - auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); + Renderer::GetInstance()->CreateRoundedRectGeometry(geo_, Rect{ Point{}, size }, radius); - if (SUCCEEDED(factory->CreateRoundedRectangleGeometry( - D2D1::RoundedRect( - DX::ConvertToRectF(rect), - radius_x, - radius_y - ), - &geo))) + if (geo_) { - geo_ = geo; - rect_ = rect; - radius_x_ = radius_x; - radius_y_ = radius_y; + SetSize(size); } } @@ -304,9 +201,9 @@ namespace kiwano { } - CircleActor::CircleActor(Point const& center, float radius) + CircleActor::CircleActor(float radius) { - SetCircle(center, radius); + SetRadius(radius); } CircleActor::~CircleActor() @@ -315,29 +212,11 @@ namespace kiwano void CircleActor::SetRadius(float radius) { - SetCircle(center_, radius); - } + Renderer::GetInstance()->CreateEllipseGeometry(geo_, Point{}, Vec2{ radius, radius }); - void CircleActor::SetCenter(Point const& center) - { - SetCircle(center, radius_); - } - - void CircleActor::SetCircle(Point const& center, float radius) - { - ComPtr geo; - auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); - - if (SUCCEEDED(factory->CreateEllipseGeometry( - D2D1::Ellipse( - DX::ConvertToPoint2F(center), - radius, - radius), - &geo))) + if (geo_) { - geo_ = geo; - center_ = center; - radius_ = radius; + SetSize(radius * 2, radius * 2); } } @@ -347,45 +226,25 @@ namespace kiwano //------------------------------------------------------- EllipseActor::EllipseActor() - : radius_x_(0.f) - , radius_y_(0.f) { } - EllipseActor::EllipseActor(Point const& center, float radius_x, float radius_y) + EllipseActor::EllipseActor(Vec2 const& radius) { - SetEllipse(center, radius_x, radius_y); + SetRadius(radius); } EllipseActor::~EllipseActor() { } - void EllipseActor::SetRadius(float radius_x, float radius_y) + void EllipseActor::SetRadius(Vec2 const& radius) { - SetEllipse(center_, radius_x, radius_y); - } + Renderer::GetInstance()->CreateEllipseGeometry(geo_, Point{}, radius); - void EllipseActor::SetCenter(Point const& center) - { - SetEllipse(center, radius_x_, radius_y_); - } - - void EllipseActor::SetEllipse(Point const& center, float radius_x, float radius_y) - { - ComPtr geo; - auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); - - if (SUCCEEDED(factory->CreateEllipseGeometry( - D2D1::Ellipse( - DX::ConvertToPoint2F(center), - radius_x, - radius_y), - &geo))) + if (geo_) { - geo_ = geo; - radius_x_ = radius_x; - radius_y_ = radius_y; + SetSize(radius * 2); } } @@ -404,89 +263,38 @@ namespace kiwano void PathActor::BeginPath(Point const& begin_pos) { - current_geometry_ = nullptr; - - auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); - - ThrowIfFailed( - factory->CreatePathGeometry(¤t_geometry_) - ); - - ThrowIfFailed( - current_geometry_->Open(¤t_sink_) - ); - - current_sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); + sink_.BeginPath(begin_pos); } void PathActor::EndPath(bool closed) { - if (current_sink_) - { - current_sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN); - ThrowIfFailed( - current_sink_->Close() - ); - - geo_ = current_geometry_; - - current_sink_ = nullptr; - current_geometry_ = nullptr; - } + sink_.EndPath(closed); + geo_ = sink_.GetGeometry(); } void PathActor::AddLine(Point const& point) { - if (current_sink_) - current_sink_->AddLine(DX::ConvertToPoint2F(point)); + sink_.AddLine(point); } void PathActor::AddLines(Vector const& points) { - if (current_sink_ && !points.empty()) - { - current_sink_->AddLines( - reinterpret_cast(&points[0]), - static_cast(points.size()) - ); - } + sink_.AddLines(points); } void PathActor::AddBezier(Point const& point1, Point const& point2, Point const& point3) { - if (current_sink_) - { - current_sink_->AddBezier( - D2D1::BezierSegment( - DX::ConvertToPoint2F(point1), - DX::ConvertToPoint2F(point2), - DX::ConvertToPoint2F(point3) - ) - ); - } + sink_.AddBezier(point1, point2, point3); } void PathActor::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) { - if (current_sink_) - { - current_sink_->AddArc( - D2D1::ArcSegment( - DX::ConvertToPoint2F(point), - DX::ConvertToSizeF(radius), - rotation, - clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, - is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE - ) - ); - } + sink_.AddArc(point, radius, rotation, clockwise, is_small); } void PathActor::ClearPath() { - geo_ = nullptr; - current_sink_ = nullptr; - current_geometry_ = nullptr; + geo_.SetGeometry(nullptr); } } diff --git a/src/kiwano/2d/ShapeActor.h b/src/kiwano/2d/ShapeActor.h index 25498b2e..940a34df 100644 --- a/src/kiwano/2d/ShapeActor.h +++ b/src/kiwano/2d/ShapeActor.h @@ -20,7 +20,7 @@ #pragma once #include "Actor.h" -#include "../renderer/render.h" // ID2D1Geometry +#include "../renderer/Geometry.h" namespace kiwano { @@ -32,7 +32,7 @@ namespace kiwano ShapeActor(); ShapeActor( - ComPtr geometry + Geometry geometry ); virtual ~ShapeActor(); @@ -55,24 +55,6 @@ namespace kiwano // 获取外切包围盒 Rect GetBoundingBox() const override; - // 判断图形是否包含点 - bool ContainsPoint( - Point const& point - ); - - // 获取图形展开成一条直线的长度 - float GetLength(); - - // 计算面积 - float ComputeArea(); - - // 计算图形路径上点的位置和切线向量 - bool ComputePointAtLength( - float length, - Point& point, - Vec2& tangent - ); - // 设置填充颜色 void SetFillColor( const Color& color @@ -94,19 +76,19 @@ namespace kiwano ); // 设置形状 - inline void SetGeometry(ComPtr geometry) { geo_ = geometry; } + inline void SetGeometry(Geometry geometry) { geo_ = geometry; } // 获取形状 - inline ComPtr GetGeometry() const { return geo_; } + inline Geometry GetGeometry() const { return geo_; } void OnRender(Renderer* renderer) override; protected: - Color fill_color_; - Color stroke_color_; - float stroke_width_; - StrokeStyle outline_join_; - ComPtr geo_; + Color fill_color_; + Color stroke_color_; + float stroke_width_; + StrokeStyle outline_join_; + Geometry geo_; }; @@ -118,31 +100,18 @@ namespace kiwano LineActor(); LineActor( - Point const& begin, - Point const& end + Point const& end_pos ); virtual ~LineActor(); - Point const& GetBegin() const { return begin_; } + Point const& GetEndPoint() const { return end_; } - Point const& GetEnd() const { return end_; } - - void SetLine( - Point const& begin, - Point const& end - ); - - void SetBegin( - Point const& begin - ); - - void SetEnd( + void SetEndPoint( Point const& end ); protected: - Point begin_; Point end_; }; @@ -155,22 +124,17 @@ namespace kiwano RectActor(); RectActor( - Rect const& rect - ); - - RectActor( - Point const& left_top, Size const& size ); virtual ~RectActor(); - Rect const& GetRect() const { return rect_; } + void SetRectSize(Size const& size); - void SetRect(Rect const& rect); + inline Size const& GetRectSize() const { return size_; } protected: - Rect rect_; + Size size_; }; @@ -182,38 +146,32 @@ namespace kiwano RoundRectActor(); RoundRectActor( - Rect const& rect, - float radius_x, - float radius_y + Size const& size, + Vec2 const& radius ); virtual ~RoundRectActor(); - float GetRadiusX() const { return radius_x_; } - - float GetRadiusY() const { return radius_y_; } - void SetRadius( - float radius_x, - float radius_y + Vec2 const& radius ); - Rect const& GetRect() const { return rect_; } - - void SetRect( - Rect const& rect + void SetRectSize( + Size const& size ); void SetRoundedRect( - Rect const& rect, - float radius_x, - float radius_y + Size const& size, + Vec2 const& radius ); + inline Vec2 GetRadius() const { return radius_; } + + inline Size GetRectSize() const { return size_; } + protected: - Rect rect_; - float radius_x_; - float radius_y_; + Size size_; + Vec2 radius_; }; @@ -225,31 +183,16 @@ namespace kiwano CircleActor(); CircleActor( - Point const& center, float radius ); virtual ~CircleActor(); - float GetRadius() const { return radius_; } + inline float GetRadius() const { return radius_; } - void SetRadius( - float radius - ); - - Point const& GetCenter() const { return center_; } - - void SetCenter( - Point const& center - ); - - void SetCircle( - Point const& center, - float radius - ); + void SetRadius(float radius); protected: - Point center_; float radius_; }; @@ -262,38 +205,19 @@ namespace kiwano EllipseActor(); EllipseActor( - Point const& center, - float radius_x, - float radius_y + Vec2 const& radius ); virtual ~EllipseActor(); - float GetRadiusX() const { return radius_x_; } - - float GetRadiusY() const { return radius_y_; } + Vec2 GetRadius() const { return radius_; } void SetRadius( - float radius_x, - float radius_y - ); - - Point const& GetCenter() const { return center_; } - - void SetCenter( - Point const& center - ); - - void SetEllipse( - Point const& center, - float radius_x, - float radius_y + Vec2 const& radius ); protected: - Point center_; - float radius_x_; - float radius_y_; + Vec2 radius_; }; @@ -346,8 +270,7 @@ namespace kiwano void ClearPath(); protected: - ComPtr current_geometry_; - ComPtr current_sink_; + GeometrySink sink_; }; } diff --git a/src/kiwano/2d/Sprite.cpp b/src/kiwano/2d/Sprite.cpp index 301747aa..0223fe08 100644 --- a/src/kiwano/2d/Sprite.cpp +++ b/src/kiwano/2d/Sprite.cpp @@ -88,6 +88,7 @@ namespace kiwano if (frame_ && renderer->CheckVisibility(size_, transform_matrix_)) { PrepareRender(renderer); + renderer->DrawBitmap(frame_->GetImage()->GetBitmap(), frame_->GetCropRect(), GetBounds()); } } diff --git a/src/kiwano/2d/action/ActionDelay.cpp b/src/kiwano/2d/action/ActionDelay.cpp new file mode 100644 index 00000000..7f784431 --- /dev/null +++ b/src/kiwano/2d/action/ActionDelay.cpp @@ -0,0 +1,40 @@ +// 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 "ActionDelay.h" + +namespace kiwano +{ + ActionDelay::ActionDelay(Duration delay) + { + SetDelay(delay); + } + + ActionPtr ActionDelay::Clone() const + { + return new ActionDelay(delay_); + } + + ActionPtr ActionDelay::Reverse() const + { + return new ActionDelay(delay_); + } + +} diff --git a/src/kiwano/2d/action/ActionDelay.h b/src/kiwano/2d/action/ActionDelay.h new file mode 100644 index 00000000..3c3dfd10 --- /dev/null +++ b/src/kiwano/2d/action/ActionDelay.h @@ -0,0 +1,41 @@ +// 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. + +#pragma once +#include "Action.h" + +namespace kiwano +{ + // 延时动作 + class KGE_API ActionDelay + : public Action + { + public: + ActionDelay( + Duration delay /* 持续时长 */ + ); + + // 获取该动作的拷贝对象 + ActionPtr Clone() const override; + + // 获取该动作的倒转 + ActionPtr Reverse() const override; + }; +} diff --git a/src/kiwano/2d/action/ActionHelper.h b/src/kiwano/2d/action/ActionHelper.h index 4735b1e6..c8d396f3 100644 --- a/src/kiwano/2d/action/ActionHelper.h +++ b/src/kiwano/2d/action/ActionHelper.h @@ -19,8 +19,10 @@ // THE SOFTWARE. #pragma once -#include "ActionGroup.h" #include "ActionTween.h" +#include "ActionWalk.h" +#include "ActionDelay.h" +#include "ActionGroup.h" #include "Animation.h" namespace kiwano @@ -185,6 +187,32 @@ namespace kiwano return TweenHelper(new kiwano::ActionRotateTo(dur, rotation)); } + static inline TweenHelper + Walk( + Duration duration, /* 持续时长 */ + Geometry const& geo, /* 路线 */ + bool rotating = false, /* 沿路线切线方向旋转 */ + float start = 0.f, /* 起点 */ + float end = 1.f, /* 终点 */ + EaseFunc func = nullptr /* 速度变化 */ + ) + { + return TweenHelper(new kiwano::ActionWalk(duration, geo, rotating, start, end, func)); + } + + static inline TweenHelper + Walk( + Duration duration, /* 持续时长 */ + GeometrySink& sink, /* 路线生成器 */ + bool rotating = false, /* 沿路线切线方向旋转 */ + float start = 0.f, /* 起点 */ + float end = 1.f, /* 终点 */ + EaseFunc func = nullptr /* 速度变化 */ + ) + { + return TweenHelper(new kiwano::ActionWalk(duration, sink.GetGeometry(), rotating, start, end, func)); + } + static inline TweenHelper Animation(Duration dur, FrameSequencePtr frames) { @@ -220,7 +248,7 @@ namespace kiwano KGE_DEPRECATED("Tween::OpacityBy has been removed, use Tween::FadeTo instead") static inline TweenHelper - OpacityBy(float opacity) + OpacityBy(float opacity) { KGE_ASSERT("Tween::OpacityBy has been removed, use Tween::FadeTo instead"); return TweenHelper(nullptr); @@ -242,7 +270,7 @@ namespace kiwano KGE_DEPRECATED("Tween::Spawn is deprecated, use Tween::Multiple instead") static inline ActionHelper - Spawn(Vector const& actions) + Spawn(Vector const& actions) { return ActionHelper(new kiwano::ActionGroup(actions, false)); } diff --git a/src/kiwano/2d/action/ActionTween.cpp b/src/kiwano/2d/action/ActionTween.cpp index 0bb1e597..b78c8720 100644 --- a/src/kiwano/2d/action/ActionTween.cpp +++ b/src/kiwano/2d/action/ActionTween.cpp @@ -419,218 +419,6 @@ namespace kiwano } - //------------------------------------------------------- - // ActionPath - //------------------------------------------------------- - - ActionPath::ActionPath(Duration duration, bool rotating, float start, float end, EaseFunc func) - : ActionTween(duration, func) - , start_(start) - , end_(end) - , rotating_(rotating) - , path_beginning_(false) - , geo_(nullptr) - , geo_sink_(nullptr) - { - } - - ActionPtr ActionPath::Clone() const - { - ActionPathPtr clone = new ActionPath(dur_, rotating_, start_, end_, ease_func_); - if (clone) - { - clone->SetGeometry(geo_); - } - return clone; - } - - ActionPtr ActionPath::Reverse() const - { - ActionPathPtr reverse = new ActionPath(dur_, rotating_, end_, start_, ease_func_); - if (reverse) - { - reverse->SetGeometry(geo_); - } - return reverse; - } - - float ActionPath::GetPathLength() const - { - float length = 0.f; - if (geo_) - { - // no matter it failed or not - geo_->ComputeLength(D2D1::Matrix3x2F::Identity(), &length); - } - return length; - } - - bool ActionPath::ComputePointAtLength(float length, Point* point, Vec2* tangent) const - { - if (geo_) - { - HRESULT hr = geo_->ComputePointAtLength( - length, - D2D1::Matrix3x2F::Identity(), - DX::ConvertToPoint2F(point), - DX::ConvertToPoint2F(tangent) - ); - return SUCCEEDED(hr); - } - return false; - } - - void ActionPath::Init(ActorPtr target) - { - start_pos_ = target->GetPosition(); - - if (path_beginning_) - { - EndPath(); - } - - if (!geo_) - { - Complete(target); - } - } - - void ActionPath::UpdateTween(ActorPtr target, float percent) - { - float length = GetPathLength() * std::min(std::max((end_ - start_) * percent + start_, 0.f), 1.f); - - Point point, tangent; - if (ComputePointAtLength(length, &point, &tangent)) - { - target->SetPosition(start_pos_ + point); - - if (rotating_) - { - float ac = math::Acos(tangent.x); - float rotation = (tangent.y < 0.f) ? 360.f - ac : ac; - target->SetRotation(rotation); - } - } - } - - void ActionPath::BeginPath() - { - if (path_beginning_) return; - path_beginning_ = true; - - geo_ = nullptr; - geo_sink_ = nullptr; - - auto factory = Renderer::GetInstance()->GetD2DDeviceResources()->GetFactory(); - - ThrowIfFailed( - factory->CreatePathGeometry(&geo_) - ); - - ThrowIfFailed( - geo_->Open(&geo_sink_) - ); - - geo_sink_->BeginFigure(DX::ConvertToPoint2F(Point{ 0, 0 }), D2D1_FIGURE_BEGIN_FILLED); - } - - void ActionPath::EndPath(bool closed) - { - if (!path_beginning_) return; - path_beginning_ = false; - - if (geo_sink_) - { - geo_sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN); - ThrowIfFailed( - geo_sink_->Close() - ); - - // Clear geometry sink - geo_sink_ = nullptr; - } - } - - void ActionPath::AddLine(Point const& point) - { - if (!path_beginning_) - { - BeginPath(); - } - - if (geo_sink_) - { - geo_sink_->AddLine(DX::ConvertToPoint2F(point)); - } - } - - void ActionPath::AddLines(Vector const& points) - { - if (!path_beginning_) - { - BeginPath(); - } - - if (geo_sink_ && !points.empty()) - { - geo_sink_->AddLines( - reinterpret_cast(&points[0]), - static_cast(points.size()) - ); - } - } - - void ActionPath::AddBezier(Point const& point1, Point const& point2, Point const& point3) - { - if (!path_beginning_) - { - BeginPath(); - } - - if (geo_sink_) - { - geo_sink_->AddBezier( - D2D1::BezierSegment( - DX::ConvertToPoint2F(point1), - DX::ConvertToPoint2F(point2), - DX::ConvertToPoint2F(point3) - ) - ); - } - } - - void ActionPath::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) - { - if (!path_beginning_) - { - BeginPath(); - } - - if (geo_sink_) - { - geo_sink_->AddArc( - D2D1::ArcSegment( - DX::ConvertToPoint2F(point), - DX::ConvertToSizeF(radius), - rotation, - clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, - is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE - ) - ); - } - } - - void ActionPath::ClearPath() - { - if (path_beginning_) - { - EndPath(); - } - - geo_sink_ = nullptr; - geo_ = nullptr; - } - //------------------------------------------------------- // ActionCustom //------------------------------------------------------- @@ -658,24 +446,4 @@ namespace kiwano tween_func_(target, percent); } - - //------------------------------------------------------- - // ActionDelay - //------------------------------------------------------- - - ActionDelay::ActionDelay(Duration delay) - { - SetDelay(delay); - } - - ActionPtr ActionDelay::Clone() const - { - return new ActionDelay(delay_); - } - - ActionPtr ActionDelay::Reverse() const - { - return new ActionDelay(delay_); - } - } diff --git a/src/kiwano/2d/action/ActionTween.h b/src/kiwano/2d/action/ActionTween.h index 43e7d240..46854a7c 100644 --- a/src/kiwano/2d/action/ActionTween.h +++ b/src/kiwano/2d/action/ActionTween.h @@ -21,7 +21,6 @@ #pragma once #include "Action.h" #include "../../base/logs.h" -#include "../../renderer/render.h" // ID2D1PathGeometry, ID2D1GeometrySink namespace kiwano { @@ -412,91 +411,6 @@ namespace kiwano }; - // 路径动作 - class KGE_API ActionPath - : public ActionTween - { - public: - ActionPath( - Duration duration, /* 持续时长 */ - bool rotating = false, /* 沿路径切线方向旋转 */ - float start = 0.f, /* 起点 */ - float end = 1.f, /* 终点 */ - EaseFunc func = nullptr /* 速度变化 */ - ); - - // 获取该动作的拷贝对象 - ActionPtr Clone() const override; - - // 获取该动作的倒转 - ActionPtr Reverse() const override; - - // 开始添加路径 - void BeginPath(); - - // 结束路径 - void EndPath( - bool closed = false /* 路径是否闭合 */ - ); - - // 添加一条线段 - void AddLine( - Point const& point /* 端点 */ - ); - - // 添加多条线段 - void AddLines( - Vector const& points - ); - - // 添加一条三次方贝塞尔曲线 - void AddBezier( - Point const& point1, /* 贝塞尔曲线的第一个控制点 */ - Point const& point2, /* 贝塞尔曲线的第二个控制点 */ - Point const& point3 /* 贝塞尔曲线的终点 */ - ); - - // 添加弧线 - void AddArc( - Point const& point, /* 终点 */ - Size const& radius, /* 椭圆半径 */ - float rotation, /* 椭圆旋转角度 */ - bool clockwise = true, /* 顺时针 or 逆时针 */ - bool is_small = true /* 是否取小于 180° 的弧 */ - ); - - // 清除路径 - void ClearPath(); - - // 获取路径长度 - float GetPathLength() const; - - // 计算当前路径上指定点坐标和切线 - bool ComputePointAtLength(float length, Point* point, Vec2* tangent) const; - - // 获取几何路径 - inline ComPtr GetGeometry() const { return geo_; } - - // 设置几何路径 - inline void SetGeometry(ComPtr geo) { geo_ = geo; } - - protected: - void Init(ActorPtr target) override; - - void UpdateTween(ActorPtr target, float percent) override; - - protected: - bool path_beginning_; - bool rotating_; - float start_; - float end_; - Point start_pos_; - - ComPtr geo_; - ComPtr geo_sink_; - }; - - // 自定义动作 class KGE_API ActionCustom : public ActionTween @@ -529,20 +443,4 @@ namespace kiwano TweenFunc tween_func_; }; - - // 延时动作 - class KGE_API ActionDelay - : public Action - { - public: - ActionDelay( - Duration delay /* 持续时长 */ - ); - - // 获取该动作的拷贝对象 - ActionPtr Clone() const override; - - // 获取该动作的倒转 - ActionPtr Reverse() const override; - }; } diff --git a/src/kiwano/2d/action/ActionWalk.cpp b/src/kiwano/2d/action/ActionWalk.cpp new file mode 100644 index 00000000..addf325e --- /dev/null +++ b/src/kiwano/2d/action/ActionWalk.cpp @@ -0,0 +1,128 @@ +// 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 "ActionWalk.h" +#include "../Actor.h" + +namespace kiwano +{ + ActionWalk::ActionWalk(Duration duration, bool rotating, float start, float end, EaseFunc func) + : ActionTween(duration, func) + , start_(start) + , end_(end) + , rotating_(rotating) + , length_(0.f) + { + } + + ActionWalk::ActionWalk(Duration duration, Geometry const& path, bool rotating, float start, float end, EaseFunc func) + : ActionWalk(duration, rotating, start, end, func) + { + path_ = path; + } + + ActionPtr ActionWalk::Clone() const + { + ActionWalkPtr clone = new ActionWalk(dur_, rotating_, start_, end_, ease_func_); + if (clone) + { + clone->SetPath(path_); + } + return clone; + } + + ActionPtr ActionWalk::Reverse() const + { + ActionWalkPtr reverse = new ActionWalk(dur_, rotating_, end_, start_, ease_func_); + if (reverse) + { + reverse->SetPath(path_); + } + return reverse; + } + + void ActionWalk::Init(ActorPtr target) + { + if (!path_) + { + Complete(target); + return; + } + + start_pos_ = target->GetPosition(); + length_ = path_.GetLength(); + } + + void ActionWalk::UpdateTween(ActorPtr target, float percent) + { + float distance = length_ * std::min(std::max((end_ - start_) * percent + start_, 0.f), 1.f); + + Point point, tangent; + if (path_.ComputePointAtLength(distance, point, tangent)) + { + target->SetPosition(start_pos_ + point); + + if (rotating_) + { + float ac = math::Acos(tangent.x); + float rotation = (tangent.y < 0.f) ? 360.f - ac : ac; + target->SetRotation(rotation); + } + } + KGE_LOG(L"%.2f, %.2f", target->GetPositionX(), target->GetPositionY()); + } + + void ActionWalk::BeginPath() + { + sink_.BeginPath(); + } + + void ActionWalk::EndPath(bool closed) + { + sink_.EndPath(closed); + path_ = sink_.GetGeometry(); + } + + void ActionWalk::AddLine(Point const& point) + { + sink_.AddLine(point); + } + + void ActionWalk::AddLines(Vector const& points) + { + sink_.AddLines(points); + } + + void ActionWalk::AddBezier(Point const& point1, Point const& point2, Point const& point3) + { + sink_.AddBezier(point1, point2, point3); + } + + void ActionWalk::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) + { + sink_.AddArc(point, radius, rotation, clockwise, is_small); + } + + void ActionWalk::ClearPath() + { + path_.SetGeometry(nullptr); + } + +} diff --git a/src/kiwano/2d/action/ActionWalk.h b/src/kiwano/2d/action/ActionWalk.h new file mode 100644 index 00000000..f9747556 --- /dev/null +++ b/src/kiwano/2d/action/ActionWalk.h @@ -0,0 +1,112 @@ +// 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. + +#pragma once +#include "ActionTween.h" +#include "../../renderer/Geometry.h" // Geometry, GeometrySink + +namespace kiwano +{ + // 路线行走动作 + class KGE_API ActionWalk + : public ActionTween + { + public: + ActionWalk( + Duration duration, /* 持续时长 */ + bool rotating = false, /* 沿路线切线方向旋转 */ + float start = 0.f, /* 起点 */ + float end = 1.f, /* 终点 */ + EaseFunc func = nullptr /* 速度变化 */ + ); + + ActionWalk( + Duration duration, /* 持续时长 */ + Geometry const& path, /* 路线 */ + bool rotating = false, /* 沿路线切线方向旋转 */ + float start = 0.f, /* 起点 */ + float end = 1.f, /* 终点 */ + EaseFunc func = nullptr /* 速度变化 */ + ); + + // 获取该动作的拷贝对象 + ActionPtr Clone() const override; + + // 获取该动作的倒转 + ActionPtr Reverse() const override; + + // 开始添加路线 + void BeginPath(); + + // 结束路线 + void EndPath( + bool closed = false /* 路线是否闭合 */ + ); + + // 添加一条线段 + void AddLine( + Point const& point /* 端点 */ + ); + + // 添加多条线段 + void AddLines( + Vector const& points + ); + + // 添加一条三次方贝塞尔曲线 + void AddBezier( + Point const& point1, /* 贝塞尔曲线的第一个控制点 */ + Point const& point2, /* 贝塞尔曲线的第二个控制点 */ + Point const& point3 /* 贝塞尔曲线的终点 */ + ); + + // 添加弧线 + void AddArc( + Point const& point, /* 终点 */ + Size const& radius, /* 椭圆半径 */ + float rotation, /* 椭圆旋转角度 */ + bool clockwise = true, /* 顺时针 or 逆时针 */ + bool is_small = true /* 是否取小于 180° 的弧 */ + ); + + // 清除路径 + void ClearPath(); + + // 获取路线 + inline Geometry GetPath() const { return path_; } + + // 设置路径 + inline void SetPath(Geometry path) { path_ = path; } + + protected: + void Init(ActorPtr target) override; + + void UpdateTween(ActorPtr target, float percent) override; + + protected: + bool rotating_; + float start_; + float end_; + float length_; + Point start_pos_; + Geometry path_; + GeometrySink sink_; + }; +} diff --git a/src/kiwano/2d/include-forwards.h b/src/kiwano/2d/include-forwards.h index 35f39f36..98f832e4 100644 --- a/src/kiwano/2d/include-forwards.h +++ b/src/kiwano/2d/include-forwards.h @@ -62,7 +62,7 @@ namespace kiwano KGE_DECLARE_SMART_PTR(ActionFadeOut); KGE_DECLARE_SMART_PTR(ActionRotateBy); KGE_DECLARE_SMART_PTR(ActionRotateTo); - KGE_DECLARE_SMART_PTR(ActionPath); + KGE_DECLARE_SMART_PTR(ActionWalk); KGE_DECLARE_SMART_PTR(Animation); KGE_DECLARE_SMART_PTR(ActionGroup); KGE_DECLARE_SMART_PTR(ActionSpawn); diff --git a/src/kiwano/kiwano.h b/src/kiwano/kiwano.h index 6a2d0c7a..76c05fd6 100644 --- a/src/kiwano/kiwano.h +++ b/src/kiwano/kiwano.h @@ -92,6 +92,8 @@ #include "2d/action/Action.h" #include "2d/action/ActionGroup.h" #include "2d/action/ActionTween.h" +#include "2d/action/ActionWalk.h" +#include "2d/action/ActionDelay.h" #include "2d/action/Animation.h" #include "2d/action/ActionHelper.h" #include "2d/action/ActionManager.h" diff --git a/src/kiwano/renderer/Geometry.cpp b/src/kiwano/renderer/Geometry.cpp new file mode 100644 index 00000000..2814ac8a --- /dev/null +++ b/src/kiwano/renderer/Geometry.cpp @@ -0,0 +1,203 @@ +// 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 "Geometry.h" +#include "render.h" +#include "../base/logs.h" + +namespace kiwano +{ + + // + // Geometry + // + + Geometry::Geometry() + { + } + + Geometry::Geometry(ComPtr geo) + : geo_(geo) + { + } + + Rect Geometry::GetBoundingBox(Matrix const& transform) const + { + if (!geo_) + return Rect{}; + + D2D1_RECT_F 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 }; + } + + float Geometry::GetLength() + { + float length = 0.f; + if (geo_) + { + // no matter it failed or not + geo_->ComputeLength(D2D1::Matrix3x2F::Identity(), &length); + } + return length; + } + + bool Geometry::ComputePointAtLength(float length, Point& point, Vec2& tangent) + { + if (geo_) + { + HRESULT hr = geo_->ComputePointAtLength( + length, + D2D1::Matrix3x2F::Identity(), + DX::ConvertToPoint2F(&point), + DX::ConvertToPoint2F(&tangent) + ); + + return SUCCEEDED(hr); + } + return false; + } + + float Geometry::ComputeArea() + { + if (!geo_) + return 0.f; + + float area = 0.f; + // no matter it failed or not + geo_->ComputeArea(D2D1::Matrix3x2F::Identity(), &area); + return area; + } + + bool Geometry::ContainsPoint(Point const& point) + { + if (!geo_) + return false; + + BOOL ret = 0; + // no matter it failed or not + geo_->FillContainsPoint( + DX::ConvertToPoint2F(point), + D2D1::Matrix3x2F::Identity(), + &ret + ); + return !!ret; + } + + // + // GeometrySink + // + + GeometrySink::GeometrySink() + { + } + + GeometrySink& GeometrySink::BeginPath(Point const& begin_pos) + { + if (!path_geo_) + { + Renderer::GetInstance()->CreatePathGeometrySink(*this); + } + + if (!sink_) + { + ThrowIfFailed(path_geo_->Open(&sink_)); + } + + if (sink_) + { + sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); + } + return (*this); + } + + GeometrySink& GeometrySink::EndPath(bool closed) + { + if (sink_) + { + sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN); + + ThrowIfFailed(sink_->Close()); + + sink_ = nullptr; + } + return (*this); + } + + GeometrySink& GeometrySink::AddLine(Point const& point) + { + if (!sink_) BeginPath(); + + sink_->AddLine(DX::ConvertToPoint2F(point)); + return (*this); + } + + GeometrySink& GeometrySink::AddLines(Vector const& points) + { + if (!sink_) BeginPath(); + + sink_->AddLines( + reinterpret_cast(&points[0]), + static_cast(points.size()) + ); + return (*this); + } + + GeometrySink& GeometrySink::AddBezier(Point const& point1, Point const& point2, Point const& point3) + { + if (!sink_) BeginPath(); + + sink_->AddBezier( + D2D1::BezierSegment( + DX::ConvertToPoint2F(point1), + DX::ConvertToPoint2F(point2), + DX::ConvertToPoint2F(point3) + ) + ); + return (*this); + } + + GeometrySink& GeometrySink::AddArc(Point const& point, Size const& radius, float rotation, bool clockwise, bool is_small) + { + if (!sink_) BeginPath(); + + sink_->AddArc( + D2D1::ArcSegment( + DX::ConvertToPoint2F(point), + DX::ConvertToSizeF(radius), + rotation, + clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, + is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE + ) + ); + return (*this); + } + + Geometry GeometrySink::GetGeometry() + { + if (sink_) + { + EndPath(); + } + return Geometry(path_geo_); + } + +} diff --git a/src/kiwano/renderer/Geometry.h b/src/kiwano/renderer/Geometry.h new file mode 100644 index 00000000..0217dde9 --- /dev/null +++ b/src/kiwano/renderer/Geometry.h @@ -0,0 +1,126 @@ +// 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. + +#pragma once +#include "../base/SmartPtr.hpp" +#include "D2DDeviceResources.h" + +namespace kiwano +{ + // 几何体 + class KGE_API Geometry + { + public: + // 获取外切包围盒 + Rect GetBoundingBox( + Matrix const& transform = Matrix() + ) const; + + // 判断图形是否包含点 + bool ContainsPoint( + Point const& point + ); + + // 获取图形展开成一条直线的长度 + float GetLength(); + + // 计算面积 + float ComputeArea(); + + // 计算图形路径上点的位置和切线向量 + bool ComputePointAtLength( + float length, + Point& point, + Vec2& tangent + ); + + public: + Geometry(); + + Geometry(ComPtr geo); + + public: + inline ComPtr GetGeometry() const { return geo_; } + + inline void SetGeometry(ComPtr geometry) { geo_ = geometry; } + + inline operator bool() const { return static_cast(geo_); } + + protected: + ComPtr geo_; + }; + + + // 几何体生成器 + class KGE_API GeometrySink + : protected noncopyable + { + public: + GeometrySink(); + + // 开始添加路径 + GeometrySink& BeginPath( + Point const& begin_pos = Point{} /* 起始点 */ + ); + + // 结束路径 + GeometrySink& EndPath( + bool closed = false /* 路径是否闭合 */ + ); + + // 添加一条线段 + GeometrySink& AddLine( + Point const& point /* 端点 */ + ); + + // 添加多条线段 + GeometrySink& AddLines( + Vector const& points + ); + + // 添加一条三次方贝塞尔曲线 + GeometrySink& AddBezier( + Point const& point1, /* 贝塞尔曲线的第一个控制点 */ + Point const& point2, /* 贝塞尔曲线的第二个控制点 */ + Point const& point3 /* 贝塞尔曲线的终点 */ + ); + + // 添加弧线 + GeometrySink& AddArc( + Point const& point, /* 终点 */ + Size const& radius, /* 椭圆半径 */ + float rotation, /* 椭圆旋转角度 */ + bool clockwise = true, /* 顺时针 or 逆时针 */ + bool is_small = true /* 是否取小于 180° 的弧 */ + ); + + // 获取生成路径几何体 + Geometry GetGeometry(); + + public: + inline ComPtr GetPathGeometry() const { return path_geo_; } + + inline void SetPathGeometry(ComPtr path) { path_geo_ = path; } + + protected: + ComPtr path_geo_; + ComPtr sink_; + }; +} diff --git a/src/kiwano/renderer/Image.h b/src/kiwano/renderer/Image.h index c3d6ee89..295d1e72 100644 --- a/src/kiwano/renderer/Image.h +++ b/src/kiwano/renderer/Image.h @@ -20,7 +20,7 @@ #pragma once #include "../base/Resource.h" -#include "render.h" // ID2D1Bitmap +#include "D2DDeviceResources.h" // ID2D1Bitmap namespace kiwano { diff --git a/src/kiwano/renderer/render.cpp b/src/kiwano/renderer/render.cpp index 984855d3..3829fb2c 100644 --- a/src/kiwano/renderer/render.cpp +++ b/src/kiwano/renderer/render.cpp @@ -132,13 +132,16 @@ namespace kiwano { HRESULT hr = S_OK; + solid_color_brush_.reset(); hr = device_context_->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::White), + D2D1::BrushProperties(), &solid_color_brush_ ); if (SUCCEEDED(hr)) { + text_renderer_.reset(); hr = ITextRenderer::Create( &text_renderer_, device_context_.get() @@ -242,8 +245,144 @@ namespace kiwano ThrowIfFailed(hr); } + void Renderer::CreateLineGeometry(Geometry& geo, Point const& begin_pos, Point const& end_pos) + { + HRESULT hr = S_OK; + if (!device_context_ || !d2d_res_) + { + hr = E_UNEXPECTED; + } + + ComPtr path_geo; + ComPtr path_sink; + if (SUCCEEDED(hr)) + { + hr = d2d_res_->GetFactory()->CreatePathGeometry(&path_geo); + } + + if (SUCCEEDED(hr)) + { + hr = path_geo->Open(&path_sink); + } + + if (SUCCEEDED(hr)) + { + path_sink->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); + path_sink->AddLine(DX::ConvertToPoint2F(end_pos)); + path_sink->EndFigure(D2D1_FIGURE_END_OPEN); + hr = path_sink->Close(); + } + + if (SUCCEEDED(hr)) + { + geo.SetGeometry(path_geo); + } + + ThrowIfFailed(hr); + } + + void Renderer::CreateRectGeometry(Geometry& geo, Rect const& rect) + { + HRESULT hr = S_OK; + if (!device_context_ || !d2d_res_) + { + hr = E_UNEXPECTED; + } + + ComPtr output; + if (SUCCEEDED(hr)) + { + hr = d2d_res_->GetFactory()->CreateRectangleGeometry(DX::ConvertToRectF(rect), &output); + } + + if (SUCCEEDED(hr)) + { + geo.SetGeometry(output); + } + + ThrowIfFailed(hr); + } + + void Renderer::CreateRoundedRectGeometry(Geometry& geo, Rect const& rect, Vec2 const& radius) + { + HRESULT hr = S_OK; + if (!device_context_ || !d2d_res_) + { + hr = E_UNEXPECTED; + } + + ComPtr output; + if (SUCCEEDED(hr)) + { + hr = d2d_res_->GetFactory()->CreateRoundedRectangleGeometry( + D2D1::RoundedRect( + DX::ConvertToRectF(rect), + radius.x, + radius.y + ), + &output); + } + + if (SUCCEEDED(hr)) + { + geo.SetGeometry(output); + } + + ThrowIfFailed(hr); + } + + void Renderer::CreateEllipseGeometry(Geometry& geo, Point const& center, Vec2 const& radius) + { + HRESULT hr = S_OK; + if (!device_context_ || !d2d_res_) + { + hr = E_UNEXPECTED; + } + + ComPtr output; + if (SUCCEEDED(hr)) + { + hr = d2d_res_->GetFactory()->CreateEllipseGeometry( + D2D1::Ellipse( + DX::ConvertToPoint2F(center), + radius.x, + radius.y + ), + &output); + } + + if (SUCCEEDED(hr)) + { + geo.SetGeometry(output); + } + + ThrowIfFailed(hr); + } + + void Renderer::CreatePathGeometrySink(GeometrySink& sink) + { + HRESULT hr = S_OK; + if (!device_context_ || !d2d_res_) + { + hr = E_UNEXPECTED; + } + + ComPtr output; + if (SUCCEEDED(hr)) + { + hr = d2d_res_->GetFactory()->CreatePathGeometry(&output); + } + + if (SUCCEEDED(hr)) + { + sink.SetPathGeometry(output); + } + + ThrowIfFailed(hr); + } + void Renderer::DrawGeometry( - ComPtr const& geometry, + Geometry const& geometry, Color const& stroke_color, float stroke_width, StrokeStyle stroke @@ -255,12 +394,12 @@ namespace kiwano hr = E_UNEXPECTED; } - if (SUCCEEDED(hr)) + if (SUCCEEDED(hr) && geometry.GetGeometry()) { solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color)); device_context_->DrawGeometry( - geometry.get(), + geometry.GetGeometry().get(), solid_color_brush_.get(), stroke_width, d2d_res_->GetStrokeStyle(stroke) @@ -272,7 +411,7 @@ namespace kiwano ThrowIfFailed(hr); } - void Renderer::FillGeometry(ComPtr const & geometry, Color const& fill_color) + void Renderer::FillGeometry(Geometry const & geometry, Color const& fill_color) { HRESULT hr = S_OK; if (!solid_color_brush_ || !device_context_) @@ -280,11 +419,11 @@ namespace kiwano hr = E_UNEXPECTED; } - if (SUCCEEDED(hr)) + if (SUCCEEDED(hr) && geometry.GetGeometry()) { solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color)); device_context_->FillGeometry( - geometry.get(), + geometry.GetGeometry().get(), solid_color_brush_.get() ); } @@ -292,7 +431,7 @@ namespace kiwano ThrowIfFailed(hr); } - void Renderer::DrawRectangle(Rect const& rect, const Color& stroke_color, float stroke_width, StrokeStyle stroke) + void Renderer::DrawRectangle(Rect const& rect, Color const& stroke_color, float stroke_width, StrokeStyle stroke) { HRESULT hr = S_OK; if (!solid_color_brush_ || !device_context_) @@ -437,7 +576,7 @@ namespace kiwano D2D1_ANTIALIAS_MODE_PER_PRIMITIVE, D2D1::Matrix3x2F::Identity(), properties.opacity, - solid_color_brush_.get(), + nullptr, D2D1_LAYER_OPTIONS_NONE ), layer.get() diff --git a/src/kiwano/renderer/render.h b/src/kiwano/renderer/render.h index c796a363..50c9373c 100644 --- a/src/kiwano/renderer/render.h +++ b/src/kiwano/renderer/render.h @@ -27,8 +27,8 @@ #include "../2d/TextStyle.hpp" #include "helper.hpp" #include "Image.h" +#include "Geometry.h" #include "TextRenderer.h" -#include "D2DDeviceResources.h" #if defined(KGE_USE_DIRECTX10) # include "D3D10DeviceResources.h" @@ -56,21 +56,48 @@ namespace kiwano ComPtr& layer ); + void CreateLineGeometry( + Geometry& geo, + Point const& begin_pos, + Point const& end_pos + ); + + void CreateRectGeometry( + Geometry& geo, + Rect const& rect + ); + + void CreateRoundedRectGeometry( + Geometry& geo, + Rect const& rect, + Vec2 const& radius + ); + + void CreateEllipseGeometry( + Geometry& geo, + Point const& center, + Vec2 const& radius + ); + + void CreatePathGeometrySink( + GeometrySink& sink + ); + void DrawGeometry( - ComPtr const& geometry, + Geometry const& geometry, const Color& stroke_color, float stroke_width, StrokeStyle stroke = StrokeStyle::Miter ); void FillGeometry( - ComPtr const& geometry, + Geometry const& geometry, Color const& fill_color ); void DrawRectangle( Rect const& rect, - const Color& stroke_color, + Color const& stroke_color, float stroke_width, StrokeStyle stroke = StrokeStyle::Miter ); From f172f10d36862f7c616eb8b23d1537ca5128c5df Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Wed, 14 Aug 2019 21:52:49 +0800 Subject: [PATCH 09/11] minor --- projects/kiwano.vcxproj | 12 +- projects/kiwano.vcxproj.filters | 36 +- src/kiwano-audio/src/Sound.cpp | 2 +- src/kiwano-audio/src/Transcoder.cpp | 2 +- src/kiwano-audio/src/audio-modules.cpp | 2 +- src/kiwano-audio/src/audio.cpp | 2 +- src/kiwano-imgui/src/ImGuiModule.cpp | 2 +- src/kiwano-imgui/src/imgui_impl_dx11.cpp | 2 +- src/kiwano-network/src/HttpClient.cpp | 2 +- src/kiwano/2d/Actor.cpp | 4 +- src/kiwano/2d/Canvas.cpp | 4 +- src/kiwano/2d/DebugActor.cpp | 2 +- src/kiwano/2d/FrameSequence.cpp | 2 +- src/kiwano/2d/GifSprite.cpp | 2 +- src/kiwano/2d/GifSprite.h | 2 +- src/kiwano/2d/Layer.cpp | 2 +- src/kiwano/2d/ShapeActor.cpp | 4 +- src/kiwano/2d/Sprite.cpp | 2 +- src/kiwano/2d/Stage.cpp | 4 +- src/kiwano/2d/Text.cpp | 4 +- src/kiwano/2d/Transition.cpp | 6 +- src/kiwano/2d/action/ActionGroup.cpp | 2 +- src/kiwano/2d/action/ActionManager.cpp | 2 +- src/kiwano/2d/action/ActionTween.h | 2 +- src/kiwano/base/EventDispatcher.cpp | 2 +- src/kiwano/base/Input.cpp | 2 +- src/kiwano/base/{logs.cpp => Logger.cpp} | 2 +- src/kiwano/base/{logs.h => Logger.h} | 14 +- src/kiwano/base/Object.cpp | 2 +- src/kiwano/base/Resource.cpp | 2 +- src/kiwano/base/TimerManager.cpp | 2 +- src/kiwano/base/Window.cpp | 418 ++++++++++++++++++ src/kiwano/base/Window.h | 95 ++++ src/kiwano/base/time.cpp | 2 +- src/kiwano/kiwano.h | 6 +- src/kiwano/platform/Application.cpp | 6 +- src/kiwano/platform/modules.cpp | 2 +- src/kiwano/renderer/D2DDeviceResources.cpp | 2 +- src/kiwano/renderer/D3D10DeviceResources.cpp | 2 +- src/kiwano/renderer/D3D11DeviceResources.cpp | 2 +- src/kiwano/renderer/Geometry.cpp | 4 +- src/kiwano/renderer/GifImage.cpp | 2 +- src/kiwano/renderer/GifImage.h | 2 +- src/kiwano/renderer/Image.cpp | 2 +- src/kiwano/renderer/ImageCache.cpp | 2 +- src/kiwano/renderer/ImageCache.h | 2 +- .../renderer/{render.cpp => Renderer.cpp} | 6 +- src/kiwano/renderer/{render.h => Renderer.h} | 0 src/kiwano/ui/Button.cpp | 2 +- src/kiwano/utils/ResourceCache.cpp | 2 +- 50 files changed, 606 insertions(+), 85 deletions(-) rename src/kiwano/base/{logs.cpp => Logger.cpp} (99%) rename src/kiwano/base/{logs.h => Logger.h} (93%) create mode 100644 src/kiwano/base/Window.cpp create mode 100644 src/kiwano/base/Window.h rename src/kiwano/renderer/{render.cpp => Renderer.cpp} (99%) rename src/kiwano/renderer/{render.h => Renderer.h} (100%) diff --git a/projects/kiwano.vcxproj b/projects/kiwano.vcxproj index 6ae1c33b..2931f641 100644 --- a/projects/kiwano.vcxproj +++ b/projects/kiwano.vcxproj @@ -48,7 +48,7 @@ - + @@ -56,7 +56,7 @@ - + @@ -76,7 +76,7 @@ - + @@ -112,14 +112,14 @@ - + - + @@ -129,7 +129,7 @@ - + diff --git a/projects/kiwano.vcxproj.filters b/projects/kiwano.vcxproj.filters index f70612b5..1be66a3b 100644 --- a/projects/kiwano.vcxproj.filters +++ b/projects/kiwano.vcxproj.filters @@ -90,9 +90,6 @@ base - - base - base @@ -114,9 +111,6 @@ renderer - - renderer - renderer @@ -158,9 +152,6 @@ base - - base - base @@ -288,6 +279,15 @@ 2d\action + + base + + + base + + + renderer + @@ -320,9 +320,6 @@ base - - base - base @@ -338,9 +335,6 @@ renderer - - renderer - renderer @@ -356,9 +350,6 @@ base - - base - base @@ -443,5 +434,14 @@ 2d\action + + base + + + base + + + renderer + \ No newline at end of file diff --git a/src/kiwano-audio/src/Sound.cpp b/src/kiwano-audio/src/Sound.cpp index 12201b09..ddf88d6f 100644 --- a/src/kiwano-audio/src/Sound.cpp +++ b/src/kiwano-audio/src/Sound.cpp @@ -18,7 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include +#include #include #include "Sound.h" #include "audio.h" diff --git a/src/kiwano-audio/src/Transcoder.cpp b/src/kiwano-audio/src/Transcoder.cpp index 3f70722f..4d2d7baf 100644 --- a/src/kiwano-audio/src/Transcoder.cpp +++ b/src/kiwano-audio/src/Transcoder.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include "audio-modules.h" #include "Transcoder.h" diff --git a/src/kiwano-audio/src/audio-modules.cpp b/src/kiwano-audio/src/audio-modules.cpp index 7993ea69..19fb126c 100644 --- a/src/kiwano-audio/src/audio-modules.cpp +++ b/src/kiwano-audio/src/audio-modules.cpp @@ -18,7 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include +#include #include "audio-modules.h" namespace kiwano diff --git a/src/kiwano-audio/src/audio.cpp b/src/kiwano-audio/src/audio.cpp index 38fce8ce..b703054a 100644 --- a/src/kiwano-audio/src/audio.cpp +++ b/src/kiwano-audio/src/audio.cpp @@ -18,7 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include +#include #include "audio-modules.h" #include "audio.h" diff --git a/src/kiwano-imgui/src/ImGuiModule.cpp b/src/kiwano-imgui/src/ImGuiModule.cpp index 9a7b68aa..cd8eca18 100644 --- a/src/kiwano-imgui/src/ImGuiModule.cpp +++ b/src/kiwano-imgui/src/ImGuiModule.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include "ImGuiModule.h" #include "imgui_impl.h" diff --git a/src/kiwano-imgui/src/imgui_impl_dx11.cpp b/src/kiwano-imgui/src/imgui_impl_dx11.cpp index a5586bf4..d155a40e 100644 --- a/src/kiwano-imgui/src/imgui_impl_dx11.cpp +++ b/src/kiwano-imgui/src/imgui_impl_dx11.cpp @@ -1,6 +1,6 @@ // dear imgui: Renderer for Kiwano (DirectX11) -#include +#include #include "imgui_impl_dx11.h" // DirectX diff --git a/src/kiwano-network/src/HttpClient.cpp b/src/kiwano-network/src/HttpClient.cpp index 8dd8a82c..e175d539 100644 --- a/src/kiwano-network/src/HttpClient.cpp +++ b/src/kiwano-network/src/HttpClient.cpp @@ -18,7 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include +#include #include #include "helper.h" #include "HttpRequest.hpp" diff --git a/src/kiwano/2d/Actor.cpp b/src/kiwano/2d/Actor.cpp index 455ef8c5..b5278b31 100644 --- a/src/kiwano/2d/Actor.cpp +++ b/src/kiwano/2d/Actor.cpp @@ -20,8 +20,8 @@ #include "Actor.h" #include "Stage.h" -#include "../base/logs.h" -#include "../renderer/render.h" +#include "../base/Logger.h" +#include "../renderer/Renderer.h" namespace kiwano { diff --git a/src/kiwano/2d/Canvas.cpp b/src/kiwano/2d/Canvas.cpp index 8bb6d660..33caed18 100644 --- a/src/kiwano/2d/Canvas.cpp +++ b/src/kiwano/2d/Canvas.cpp @@ -19,8 +19,8 @@ // THE SOFTWARE. #include "Canvas.h" -#include "../base/logs.h" -#include "../renderer/render.h" +#include "../base/Logger.h" +#include "../renderer/Renderer.h" namespace kiwano { diff --git a/src/kiwano/2d/DebugActor.cpp b/src/kiwano/2d/DebugActor.cpp index aaef5c99..e7429567 100644 --- a/src/kiwano/2d/DebugActor.cpp +++ b/src/kiwano/2d/DebugActor.cpp @@ -20,7 +20,7 @@ #include "DebugActor.h" #include "Text.h" -#include "../renderer/render.h" +#include "../renderer/Renderer.h" #include #include diff --git a/src/kiwano/2d/FrameSequence.cpp b/src/kiwano/2d/FrameSequence.cpp index 0783e483..4957e1f0 100644 --- a/src/kiwano/2d/FrameSequence.cpp +++ b/src/kiwano/2d/FrameSequence.cpp @@ -20,7 +20,7 @@ #include "FrameSequence.h" #include "Frame.h" -#include "../base/logs.h" +#include "../base/Logger.h" namespace kiwano { diff --git a/src/kiwano/2d/GifSprite.cpp b/src/kiwano/2d/GifSprite.cpp index de4bb118..bccf256c 100644 --- a/src/kiwano/2d/GifSprite.cpp +++ b/src/kiwano/2d/GifSprite.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "GifSprite.h" -#include "../base/logs.h" +#include "../base/Logger.h" #include "../platform/modules.h" namespace kiwano diff --git a/src/kiwano/2d/GifSprite.h b/src/kiwano/2d/GifSprite.h index c72ddc28..0c730c7d 100644 --- a/src/kiwano/2d/GifSprite.h +++ b/src/kiwano/2d/GifSprite.h @@ -21,7 +21,7 @@ #pragma once #include "Actor.h" #include "../base/Resource.h" -#include "../renderer/render.h" +#include "../renderer/Renderer.h" #include "../renderer/GifImage.h" namespace kiwano diff --git a/src/kiwano/2d/Layer.cpp b/src/kiwano/2d/Layer.cpp index c535088e..2b709eac 100644 --- a/src/kiwano/2d/Layer.cpp +++ b/src/kiwano/2d/Layer.cpp @@ -20,7 +20,7 @@ #pragma once #include "Layer.h" -#include "../renderer/render.h" +#include "../renderer/Renderer.h" namespace kiwano { diff --git a/src/kiwano/2d/ShapeActor.cpp b/src/kiwano/2d/ShapeActor.cpp index 1e4689b5..9ff124bb 100644 --- a/src/kiwano/2d/ShapeActor.cpp +++ b/src/kiwano/2d/ShapeActor.cpp @@ -19,8 +19,8 @@ // THE SOFTWARE. #include "ShapeActor.h" -#include "../base/logs.h" -#include "../renderer/render.h" +#include "../base/Logger.h" +#include "../renderer/Renderer.h" namespace kiwano { diff --git a/src/kiwano/2d/Sprite.cpp b/src/kiwano/2d/Sprite.cpp index 0223fe08..ac4ffcba 100644 --- a/src/kiwano/2d/Sprite.cpp +++ b/src/kiwano/2d/Sprite.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "Sprite.h" -#include "../renderer/render.h" +#include "../renderer/Renderer.h" namespace kiwano { diff --git a/src/kiwano/2d/Stage.cpp b/src/kiwano/2d/Stage.cpp index 63a151ab..b694a39f 100644 --- a/src/kiwano/2d/Stage.cpp +++ b/src/kiwano/2d/Stage.cpp @@ -19,8 +19,8 @@ // THE SOFTWARE. #include "Stage.h" -#include "../base/logs.h" -#include "../renderer/render.h" +#include "../base/Logger.h" +#include "../renderer/Renderer.h" namespace kiwano { diff --git a/src/kiwano/2d/Text.cpp b/src/kiwano/2d/Text.cpp index 1c36567a..84fae7f8 100644 --- a/src/kiwano/2d/Text.cpp +++ b/src/kiwano/2d/Text.cpp @@ -19,8 +19,8 @@ // THE SOFTWARE. #include "Text.h" -#include "../base/logs.h" -#include "../renderer/render.h" +#include "../base/Logger.h" +#include "../renderer/Renderer.h" namespace kiwano { diff --git a/src/kiwano/2d/Transition.cpp b/src/kiwano/2d/Transition.cpp index b17b98c3..af2876c5 100644 --- a/src/kiwano/2d/Transition.cpp +++ b/src/kiwano/2d/Transition.cpp @@ -21,9 +21,9 @@ #include "Transition.h" #include "Actor.h" #include "Stage.h" -#include "../base/window.h" -#include "../base/logs.h" -#include "../renderer/render.h" +#include "../base/Window.h" +#include "../base/Logger.h" +#include "../renderer/Renderer.h" namespace kiwano { diff --git a/src/kiwano/2d/action/ActionGroup.cpp b/src/kiwano/2d/action/ActionGroup.cpp index 1e71db99..fd1a646a 100644 --- a/src/kiwano/2d/action/ActionGroup.cpp +++ b/src/kiwano/2d/action/ActionGroup.cpp @@ -20,7 +20,7 @@ #include "ActionGroup.h" #include "../Actor.h" -#include "../../base/logs.h" +#include "../../base/Logger.h" namespace kiwano { diff --git a/src/kiwano/2d/action/ActionManager.cpp b/src/kiwano/2d/action/ActionManager.cpp index b23df82f..3428bd8a 100644 --- a/src/kiwano/2d/action/ActionManager.cpp +++ b/src/kiwano/2d/action/ActionManager.cpp @@ -20,7 +20,7 @@ #include "ActionManager.h" #include "../Actor.h" -#include "../../base/logs.h" +#include "../../base/Logger.h" namespace kiwano { diff --git a/src/kiwano/2d/action/ActionTween.h b/src/kiwano/2d/action/ActionTween.h index 46854a7c..bb4d3b56 100644 --- a/src/kiwano/2d/action/ActionTween.h +++ b/src/kiwano/2d/action/ActionTween.h @@ -20,7 +20,7 @@ #pragma once #include "Action.h" -#include "../../base/logs.h" +#include "../../base/Logger.h" namespace kiwano { diff --git a/src/kiwano/base/EventDispatcher.cpp b/src/kiwano/base/EventDispatcher.cpp index 41fa71b9..8dc93e26 100644 --- a/src/kiwano/base/EventDispatcher.cpp +++ b/src/kiwano/base/EventDispatcher.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "EventDispatcher.h" -#include "../base/logs.h" +#include "../base/Logger.h" namespace kiwano { diff --git a/src/kiwano/base/Input.cpp b/src/kiwano/base/Input.cpp index ba52a7f5..6d4f86af 100644 --- a/src/kiwano/base/Input.cpp +++ b/src/kiwano/base/Input.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "input.h" -#include "logs.h" +#include "Logger.h" #include // GET_X_LPARAM, GET_Y_LPARAM namespace kiwano diff --git a/src/kiwano/base/logs.cpp b/src/kiwano/base/Logger.cpp similarity index 99% rename from src/kiwano/base/logs.cpp rename to src/kiwano/base/Logger.cpp index a8f2d257..7f72fc9e 100644 --- a/src/kiwano/base/logs.cpp +++ b/src/kiwano/base/Logger.cpp @@ -18,7 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include "logs.h" +#include "Logger.h" #include #include diff --git a/src/kiwano/base/logs.h b/src/kiwano/base/Logger.h similarity index 93% rename from src/kiwano/base/logs.h rename to src/kiwano/base/Logger.h index 368e2afb..af05f629 100644 --- a/src/kiwano/base/logs.h +++ b/src/kiwano/base/Logger.h @@ -27,18 +27,26 @@ #ifndef KGE_LOG # ifdef KGE_DEBUG -# define KGE_LOG(FORMAT, ...) kiwano::Logger::GetInstance()->Messagef((FORMAT ## "\n"), __VA_ARGS__) +# define KGE_LOG(FORMAT, ...) ::kiwano::Logger::GetInstance()->Messagef((FORMAT ## "\n"), __VA_ARGS__) # else # define KGE_LOG __noop # endif #endif #ifndef KGE_WARNING_LOG -# define KGE_WARNING_LOG(FORMAT, ...) kiwano::Logger::GetInstance()->Warningf((FORMAT ## "\n"), __VA_ARGS__) +# define KGE_WARNING_LOG(FORMAT, ...) ::kiwano::Logger::GetInstance()->Warningf((FORMAT ## "\n"), __VA_ARGS__) #endif #ifndef KGE_ERROR_LOG -# define KGE_ERROR_LOG(FORMAT, ...) kiwano::Logger::GetInstance()->Errorf((FORMAT ## "\n"), __VA_ARGS__) +# define KGE_ERROR_LOG(FORMAT, ...) ::kiwano::Logger::GetInstance()->Errorf((FORMAT ## "\n"), __VA_ARGS__) +#endif + +#ifndef KGE_PRINT +# define KGE_PRINT(...) ::kiwano::Logger::GetInstance()->Println(__VA_ARGS__) +#endif + +#ifndef KGE_PRINTF +# define KGE_PRINTF(FORMAT, ...) ::kiwano::Logger::GetInstance()->Printf((FORMAT), __VA_ARGS__) #endif namespace kiwano diff --git a/src/kiwano/base/Object.cpp b/src/kiwano/base/Object.cpp index d0b2b430..888e9108 100644 --- a/src/kiwano/base/Object.cpp +++ b/src/kiwano/base/Object.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "Object.h" -#include "logs.h" +#include "Logger.h" #include namespace kiwano diff --git a/src/kiwano/base/Resource.cpp b/src/kiwano/base/Resource.cpp index be2387ca..ee6c84e7 100644 --- a/src/kiwano/base/Resource.cpp +++ b/src/kiwano/base/Resource.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "Resource.h" -#include "../base/logs.h" +#include "../base/Logger.h" namespace kiwano { diff --git a/src/kiwano/base/TimerManager.cpp b/src/kiwano/base/TimerManager.cpp index 205f7613..1476e157 100644 --- a/src/kiwano/base/TimerManager.cpp +++ b/src/kiwano/base/TimerManager.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "TimerManager.h" -#include "../base/logs.h" +#include "../base/Logger.h" namespace kiwano { diff --git a/src/kiwano/base/Window.cpp b/src/kiwano/base/Window.cpp new file mode 100644 index 00000000..bc2a5f80 --- /dev/null +++ b/src/kiwano/base/Window.cpp @@ -0,0 +1,418 @@ +// 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 "Window.h" +#include "Logger.h" + +#define WINDOW_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX +#define WINDOW_FULLSCREEN_STYLE WS_CLIPCHILDREN | WS_POPUP +#define KGE_WND_CLASS_NAME L"KiwanoAppWnd" + +namespace kiwano +{ + namespace + { + MONITORINFOEX GetMoniterInfoEx(HWND hwnd); + + void AdjustWindow(UINT width, UINT height, DWORD style, UINT* win_width, UINT* win_height); + + void ChangeFullScreenResolution(int width, int height, WCHAR* device_name); + + void RestoreResolution(WCHAR* device_name); + } + + Window::Window() + : handle_(nullptr) + , width_(0) + , height_(0) + , device_name_(nullptr) + , is_fullscreen_(false) + , mouse_cursor_(MouseCursor(-1)) + { + } + + Window::~Window() + { + if (is_fullscreen_) + RestoreResolution(device_name_); + + if (device_name_) + { + delete[] device_name_; + device_name_ = nullptr; + } + + if (handle_) + { + ::DestroyWindow(handle_); + handle_ = nullptr; + } + } + + HRESULT Window::Create(String const& title, int width, int height, LPCWSTR icon, bool fullscreen, WNDPROC proc) + { + HINSTANCE hinst = GetModuleHandleW(nullptr); + WNDCLASSEX wcex = { 0 }; + wcex.cbSize = sizeof(WNDCLASSEX); + wcex.lpszClassName = KGE_WND_CLASS_NAME; + wcex.style = CS_HREDRAW | CS_VREDRAW /* | CS_DBLCLKS */; + wcex.lpfnWndProc = proc; + wcex.hIcon = nullptr; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = sizeof(LONG_PTR); + wcex.hInstance = hinst; + wcex.hbrBackground = nullptr; + wcex.lpszMenuName = nullptr; + wcex.hCursor = nullptr; + + if (icon) + { + wcex.hIcon = (HICON)::LoadImageW(hinst, icon, IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); + } + + ::RegisterClassExW(&wcex); + + // Get the nearest monitor to this window + HMONITOR monitor = ::MonitorFromPoint(POINT{ 0, 0 }, MONITOR_DEFAULTTOPRIMARY); + + // Get the target monitor info + MONITORINFOEX monitor_info_ex; + memset(&monitor_info_ex, 0, sizeof(MONITORINFOEX)); + monitor_info_ex.cbSize = sizeof(MONITORINFOEX); + ::GetMonitorInfoW(monitor, &monitor_info_ex); + + // Save the device name + int len = lstrlenW(monitor_info_ex.szDevice); + device_name_ = new WCHAR[len + 1]; + lstrcpyW(device_name_, monitor_info_ex.szDevice); + + int left = -1; + int top = -1; + + is_fullscreen_ = fullscreen; + + if (is_fullscreen_) + { + top = monitor_info_ex.rcMonitor.top; + left = monitor_info_ex.rcMonitor.left; + + if (width > monitor_info_ex.rcWork.right - left) + width = monitor_info_ex.rcWork.right - left; + + if (height > monitor_info_ex.rcWork.bottom - top) + height = monitor_info_ex.rcWork.bottom - top; + } + else + { + UINT screenw = monitor_info_ex.rcWork.right - monitor_info_ex.rcWork.left; + UINT screenh = monitor_info_ex.rcWork.bottom - monitor_info_ex.rcWork.top; + + UINT win_width, win_height; + AdjustWindow( + width, + height, + GetWindowStyle(), + &win_width, + &win_height + ); + + left = monitor_info_ex.rcWork.left + (screenw - win_width) / 2; + top = monitor_info_ex.rcWork.top + (screenh - win_height) / 2; + width = win_width; + height = win_height; + } + + handle_ = ::CreateWindowExW( + is_fullscreen_ ? WS_EX_TOPMOST : 0, + KGE_WND_CLASS_NAME, + title.c_str(), + GetWindowStyle(), + left, + top, + width, + height, + nullptr, + nullptr, + hinst, + nullptr + ); + + if (handle_ == nullptr) + { + ::UnregisterClass(KGE_WND_CLASS_NAME, hinst); + return HRESULT_FROM_WIN32(GetLastError()); + } + + RECT rc; + GetClientRect(handle_, &rc); + width_ = rc.right - rc.left; + height_ = rc.bottom - rc.top; + + SetMouseCursor(MouseCursor::Arrow); + return S_OK; + } + + void Window::Prepare() + { + ::ShowWindow(handle_, SW_SHOWNORMAL); + ::UpdateWindow(handle_); + + if (is_fullscreen_) + { + ChangeFullScreenResolution(width_, height_, device_name_); + } + } + + String Window::GetTitle() const + { + if (handle_) + { + wchar_t title[256]; + ::GetWindowTextW(handle_, title, 256); + return title; + } + return String(); + } + + void Window::SetTitle(String const& title) + { + if (handle_) + ::SetWindowTextW(handle_, title.c_str()); + } + + Size Window::GetSize() const + { + return Size{ + static_cast(width_), + static_cast(height_) + }; + } + + float Window::GetWidth() const + { + return static_cast(width_); + } + + float Window::GetHeight() const + { + return static_cast(height_); + } + + void Window::SetIcon(LPCWSTR icon_resource) + { + if (handle_) + { + HINSTANCE hinstance = GetModuleHandle(nullptr); + HICON icon = (HICON)::LoadImage( + hinstance, + icon_resource, + IMAGE_ICON, + 0, + 0, + LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE + ); + + ::SendMessage(handle_, WM_SETICON, ICON_BIG, (LPARAM)icon); + ::SendMessage(handle_, WM_SETICON, ICON_SMALL, (LPARAM)icon); + } + } + + void Window::Resize(int width, int height) + { + if (handle_ && !is_fullscreen_) + { + RECT rc = { 0, 0, int(width), int(height) }; + ::AdjustWindowRect(&rc, GetWindowStyle(), false); + + width = rc.right - rc.left; + height = rc.bottom - rc.top; + ::SetWindowPos(handle_, 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + } + } + + void Window::SetFullscreen(bool fullscreen, int width, int height) + { + if (is_fullscreen_ != fullscreen || width != width_ || height != height_) + { + is_fullscreen_ = fullscreen; + + if (is_fullscreen_) + { + // move window to (0, 0) before display switch + ::SetWindowPos(handle_, HWND_TOPMOST, 0, 0, width_, height_, SWP_NOACTIVATE); + + ChangeFullScreenResolution(width, height, device_name_); + + MONITORINFOEX info = GetMoniterInfoEx(handle_); + + ::SetWindowLongPtr(handle_, GWL_STYLE, GetWindowStyle()); + ::SetWindowPos(handle_, HWND_TOPMOST, info.rcMonitor.top, info.rcMonitor.left, width, height, SWP_NOACTIVATE); + + width_ = width; + height_ = height; + } + else + { + RestoreResolution(device_name_); + + MONITORINFOEX info = GetMoniterInfoEx(handle_); + + UINT screenw = info.rcWork.right - info.rcWork.left; + UINT screenh = info.rcWork.bottom - info.rcWork.top; + + UINT win_width, win_height; + AdjustWindow(width, height, GetWindowStyle(), &win_width, &win_height); + + int left = screenw > win_width ? ((screenw - win_width) / 2) : 0; + int top = screenh > win_height ? ((screenh - win_height) / 2) : 0; + + ::SetWindowLongPtr(handle_, GWL_STYLE, GetWindowStyle()); + ::SetWindowPos(handle_, HWND_NOTOPMOST, left, top, win_width, win_height, SWP_DRAWFRAME | SWP_FRAMECHANGED); + + UpdateWindowRect(); + } + + ::ShowWindow(handle_, SW_SHOWNORMAL); + } + } + + void Window::SetMouseCursor(MouseCursor cursor) + { + if (mouse_cursor_ != cursor) + { + mouse_cursor_ = cursor; + + LPTSTR win32_cursor = IDC_ARROW; + switch (cursor) + { + case MouseCursor::Arrow: win32_cursor = IDC_ARROW; break; + case MouseCursor::TextInput: win32_cursor = IDC_IBEAM; break; + case MouseCursor::SizeAll: win32_cursor = IDC_SIZEALL; break; + case MouseCursor::SizeWE: win32_cursor = IDC_SIZEWE; break; + case MouseCursor::SizeNS: win32_cursor = IDC_SIZENS; break; + case MouseCursor::SizeNESW: win32_cursor = IDC_SIZENESW; break; + case MouseCursor::SizeNWSE: win32_cursor = IDC_SIZENWSE; break; + case MouseCursor::Hand: win32_cursor = IDC_HAND; break; + } + ::SetCursor(::LoadCursorW(nullptr, win32_cursor)); + } + } + + HWND Window::GetHandle() const + { + return handle_; + } + + DWORD Window::GetWindowStyle() const + { + return is_fullscreen_ ? (WINDOW_FULLSCREEN_STYLE) : (WINDOW_STYLE); + } + + void Window::UpdateWindowRect() + { + if (!handle_) + return; + + RECT rc; + ::GetClientRect(handle_, &rc); + + width_ = rc.right - rc.left; + height_ = rc.bottom - rc.top; + } + + void Window::SetActive(bool actived) + { + if (!handle_) + return; + + if (is_fullscreen_) + { + if (actived) + { + ChangeFullScreenResolution(width_, height_, device_name_); + + MONITORINFOEX info = GetMoniterInfoEx(handle_); + ::SetWindowPos(handle_, HWND_TOPMOST, info.rcMonitor.top, info.rcMonitor.left, width_, height_, SWP_NOACTIVATE); + } + else + { + RestoreResolution(device_name_); + + ::SetWindowPos(handle_, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + ::ShowWindow(handle_, SW_MINIMIZE); + } + } + } + + namespace + { + MONITORINFOEX GetMoniterInfoEx(HWND hwnd) + { + HMONITOR monitor = ::MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + MONITORINFOEX monitor_info; + + memset(&monitor_info, 0, sizeof(MONITORINFOEX)); + monitor_info.cbSize = sizeof(MONITORINFOEX); + ::GetMonitorInfoW(monitor, &monitor_info); + + return monitor_info; + } + + void AdjustWindow(UINT width, UINT height, DWORD style, UINT* win_width, UINT* win_height) + { + RECT rc; + ::SetRect(&rc, 0, 0, (int)width, (int)height); + ::AdjustWindowRect(&rc, style, false); + + *win_width = rc.right - rc.left; + *win_height = rc.bottom - rc.top; + + MONITORINFOEX info = GetMoniterInfoEx(NULL); + + UINT screenw = info.rcWork.right - info.rcWork.left; + UINT screenh = info.rcWork.bottom - info.rcWork.top; + + if (*win_width > screenw) + *win_width = screenw; + if (*win_height > screenh) + *win_height = screenh; + } + + void ChangeFullScreenResolution(int width, int height, WCHAR* device_name) + { + DEVMODE mode; + + memset(&mode, 0, sizeof(mode)); + mode.dmSize = sizeof(DEVMODE); + mode.dmBitsPerPel = ::GetDeviceCaps(::GetDC(0), BITSPIXEL);; + mode.dmPelsWidth = width; + mode.dmPelsHeight = height; + mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + + if (::ChangeDisplaySettingsExW(device_name, &mode, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL) + KGE_ERROR_LOG(L"ChangeDisplaySettings failed"); + } + + void RestoreResolution(WCHAR* device_name) + { + ::ChangeDisplaySettingsExW(device_name, NULL, NULL, 0, NULL); + } + } +} diff --git a/src/kiwano/base/Window.h b/src/kiwano/base/Window.h new file mode 100644 index 00000000..bd1dc631 --- /dev/null +++ b/src/kiwano/base/Window.h @@ -0,0 +1,95 @@ +// 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. + +#pragma once +#include "../macros.h" +#include "../core/core.h" +#include "../math/helper.h" +#include "types.h" + +namespace kiwano +{ + class KGE_API Window + : public Singleton + { + KGE_DECLARE_SINGLETON(Window); + + public: + // 获取标题 + String GetTitle() const; + + // 获取窗口大小 + Size GetSize() const; + + // 获取窗口宽度 + float GetWidth() const; + + // 获取窗口高度 + float GetHeight() const; + + // 设置标题 + void SetTitle(String const& title); + + // 设置窗口图标 + void SetIcon(LPCWSTR icon_resource); + + // 重设窗口大小 + void Resize(int width, int height); + + // 设置全屏模式 + void SetFullscreen(bool fullscreen, int width, int height); + + // 设置鼠标指针 + void SetMouseCursor(MouseCursor cursor); + + public: + HRESULT Create( + String const& title, + int width, + int height, + LPCWSTR icon, + bool fullscreen, + WNDPROC proc + ); + + void Prepare(); + + HWND GetHandle() const; + + DWORD GetWindowStyle() const; + + void UpdateWindowRect(); + + void SetActive(bool actived); + + protected: + Window(); + + ~Window(); + + private: + HWND handle_; + bool is_fullscreen_; + int width_; + int height_; + WCHAR* device_name_; + MouseCursor mouse_cursor_; + }; +} diff --git a/src/kiwano/base/time.cpp b/src/kiwano/base/time.cpp index 0a5349d1..eba6b604 100644 --- a/src/kiwano/base/time.cpp +++ b/src/kiwano/base/time.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "time.h" -#include "logs.h" +#include "Logger.h" #include #include diff --git a/src/kiwano/kiwano.h b/src/kiwano/kiwano.h index 76c05fd6..92597682 100644 --- a/src/kiwano/kiwano.h +++ b/src/kiwano/kiwano.h @@ -59,15 +59,15 @@ // base // -#include "renderer/render.h" +#include "renderer/Renderer.h" #include "renderer/Image.h" #include "renderer/GifImage.h" #include "base/time.h" -#include "base/window.h" +#include "base/Window.h" #include "base/input.h" #include "base/Director.h" -#include "base/logs.h" +#include "base/Logger.h" #include "base/SmartPtr.hpp" #include "base/ComPtr.hpp" diff --git a/src/kiwano/platform/Application.cpp b/src/kiwano/platform/Application.cpp index da311c13..c47fa142 100644 --- a/src/kiwano/platform/Application.cpp +++ b/src/kiwano/platform/Application.cpp @@ -20,11 +20,11 @@ #include "Application.h" #include "modules.h" -#include "../base/window.h" -#include "../base/logs.h" +#include "../base/Window.h" +#include "../base/Logger.h" #include "../base/input.h" #include "../base/Director.h" -#include "../renderer/render.h" +#include "../renderer/Renderer.h" #include "../utils/ResourceCache.h" #include // GET_X_LPARAM, GET_Y_LPARAM #include // ImmAssociateContext diff --git a/src/kiwano/platform/modules.cpp b/src/kiwano/platform/modules.cpp index 555597af..93559f02 100644 --- a/src/kiwano/platform/modules.cpp +++ b/src/kiwano/platform/modules.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "modules.h" -#include "../base/logs.h" +#include "../base/Logger.h" namespace kiwano { diff --git a/src/kiwano/renderer/D2DDeviceResources.cpp b/src/kiwano/renderer/D2DDeviceResources.cpp index 9dfba175..e930829a 100644 --- a/src/kiwano/renderer/D2DDeviceResources.cpp +++ b/src/kiwano/renderer/D2DDeviceResources.cpp @@ -20,7 +20,7 @@ #include "D2DDeviceResources.h" #include "ImageCache.h" -#include "../base/logs.h" +#include "../base/Logger.h" #include "../utils/FileUtil.h" #pragma comment(lib, "d2d1.lib") diff --git a/src/kiwano/renderer/D3D10DeviceResources.cpp b/src/kiwano/renderer/D3D10DeviceResources.cpp index b030ccbf..db3b3839 100644 --- a/src/kiwano/renderer/D3D10DeviceResources.cpp +++ b/src/kiwano/renderer/D3D10DeviceResources.cpp @@ -20,7 +20,7 @@ #include "D3D10DeviceResources.h" -#include "../base/logs.h" +#include "../base/Logger.h" #pragma comment(lib, "d3d10_1.lib") diff --git a/src/kiwano/renderer/D3D11DeviceResources.cpp b/src/kiwano/renderer/D3D11DeviceResources.cpp index 1c7b04fa..07f052dc 100644 --- a/src/kiwano/renderer/D3D11DeviceResources.cpp +++ b/src/kiwano/renderer/D3D11DeviceResources.cpp @@ -20,7 +20,7 @@ #include "D3D11DeviceResources.h" -#include "../base/logs.h" +#include "../base/Logger.h" #include // IsWindows10OrGreater #pragma comment(lib, "d3d11.lib") diff --git a/src/kiwano/renderer/Geometry.cpp b/src/kiwano/renderer/Geometry.cpp index 2814ac8a..9d5ada2e 100644 --- a/src/kiwano/renderer/Geometry.cpp +++ b/src/kiwano/renderer/Geometry.cpp @@ -19,8 +19,8 @@ // THE SOFTWARE. #include "Geometry.h" -#include "render.h" -#include "../base/logs.h" +#include "Renderer.h" +#include "../base/Logger.h" namespace kiwano { diff --git a/src/kiwano/renderer/GifImage.cpp b/src/kiwano/renderer/GifImage.cpp index a7f565bb..d2546c51 100644 --- a/src/kiwano/renderer/GifImage.cpp +++ b/src/kiwano/renderer/GifImage.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "GifImage.h" -#include "../base/logs.h" +#include "../base/Logger.h" #include "../utils/FileUtil.h" namespace kiwano diff --git a/src/kiwano/renderer/GifImage.h b/src/kiwano/renderer/GifImage.h index 6e7d5c0c..556a2b82 100644 --- a/src/kiwano/renderer/GifImage.h +++ b/src/kiwano/renderer/GifImage.h @@ -20,7 +20,7 @@ #pragma once #include "../base/Resource.h" -#include "render.h" +#include "Renderer.h" namespace kiwano { diff --git a/src/kiwano/renderer/Image.cpp b/src/kiwano/renderer/Image.cpp index d1189c14..d01a8d91 100644 --- a/src/kiwano/renderer/Image.cpp +++ b/src/kiwano/renderer/Image.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "Image.h" -#include "../base/logs.h" +#include "../base/Logger.h" #include "../platform/modules.h" namespace kiwano diff --git a/src/kiwano/renderer/ImageCache.cpp b/src/kiwano/renderer/ImageCache.cpp index e0a048b8..342f2268 100644 --- a/src/kiwano/renderer/ImageCache.cpp +++ b/src/kiwano/renderer/ImageCache.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "ImageCache.h" -#include "../base/logs.h" +#include "../base/Logger.h" namespace kiwano { diff --git a/src/kiwano/renderer/ImageCache.h b/src/kiwano/renderer/ImageCache.h index 925e15ed..2d8365df 100644 --- a/src/kiwano/renderer/ImageCache.h +++ b/src/kiwano/renderer/ImageCache.h @@ -20,7 +20,7 @@ #pragma once #include "../core/singleton.hpp" -#include "render.h" +#include "Renderer.h" namespace kiwano { diff --git a/src/kiwano/renderer/render.cpp b/src/kiwano/renderer/Renderer.cpp similarity index 99% rename from src/kiwano/renderer/render.cpp rename to src/kiwano/renderer/Renderer.cpp index 3829fb2c..9cfe13b1 100644 --- a/src/kiwano/renderer/render.cpp +++ b/src/kiwano/renderer/Renderer.cpp @@ -18,9 +18,9 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include "render.h" -#include "../base/logs.h" -#include "../base/window.h" +#include "Renderer.h" +#include "../base/Logger.h" +#include "../base/Window.h" namespace kiwano { diff --git a/src/kiwano/renderer/render.h b/src/kiwano/renderer/Renderer.h similarity index 100% rename from src/kiwano/renderer/render.h rename to src/kiwano/renderer/Renderer.h diff --git a/src/kiwano/ui/Button.cpp b/src/kiwano/ui/Button.cpp index 746b2c49..9a8a841c 100644 --- a/src/kiwano/ui/Button.cpp +++ b/src/kiwano/ui/Button.cpp @@ -20,7 +20,7 @@ #include "Button.h" #include "../2d/Stage.h" -#include "../base/window.h" +#include "../base/Window.h" namespace kiwano { diff --git a/src/kiwano/utils/ResourceCache.cpp b/src/kiwano/utils/ResourceCache.cpp index 19122e59..b4c111c8 100644 --- a/src/kiwano/utils/ResourceCache.cpp +++ b/src/kiwano/utils/ResourceCache.cpp @@ -19,7 +19,7 @@ // THE SOFTWARE. #include "ResourceCache.h" -#include "../base/logs.h" +#include "../base/Logger.h" #include "../2d/Frame.h" #include "../2d/FrameSequence.h" #include "../renderer/GifImage.h" From 0583ad8839a58b38251b410f25bc49ccedc92e4e Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Wed, 14 Aug 2019 22:09:22 +0800 Subject: [PATCH 10/11] fix appveyor.yml --- appveyor.yml | 46 +++++++++++++++++++++++++------------- src/kiwano/base/window.cpp | 4 ++-- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index c4d1800b..dc89cd0d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,20 +2,27 @@ version: 0.9.{build} skip_tags: true +# fetch repository as zip archive +shallow_clone: true + # pull_requests: # do_not_increment_build_number: true +# Do not build feature branch with open Pull Requests +# skip_branch_with_pr: true + # image: # - Visual Studio 2019 # - Visual Studio 2017 # - Visual Studio 2015 environment: - time_out_mins: 5 - job_to_deploy: 6 # 3(images) * 1(platform) * 2(configuration) - flag_to_deploy: false - APPVEYOR_API_TOKEN: - secure: UJFCbRNHMOqQg3e3Kv/ZnaIqqwXAt+5HDldetaZsZ5E= + global: + time_out_mins: 5 + job_to_deploy: 6 # 3(images) * 1(platform) * 2(configuration) + flag_to_deploy: false + appveyor_api_token: + secure: UJFCbRNHMOqQg3e3Kv/ZnaIqqwXAt+5HDldetaZsZ5E= matrix: - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 VS_PLATFORM_TOOLSET: v142 @@ -24,6 +31,12 @@ environment: - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 VS_PLATFORM_TOOLSET: v140 +matrix: + fast_finish: true # set this flag to immediately finish build once one of the jobs fails + # allow_failures: + # - platform: x86 + # configuration: Debug + skip_commits: message: /\[chore\]/ @@ -34,14 +47,6 @@ only_commits: - scripts/**/*.ps1 - appveyor.yml -for: -- - branches: - except: - - master - only_commits: - message: /\[build\]/ - configuration: - Debug - Release @@ -62,8 +67,19 @@ build: project: projects/Kiwano.sln verbosity: minimal -after_build: -- ps: .\scripts\appveyor\wait_for_other_jobs.ps1 +for: +- + branches: + except: + - master + only_commits: + message: /\[build\]/ +- + branches: + only: + - master + after_build: + - ps: .\scripts\appveyor\wait_for_other_jobs.ps1 artifacts: - path: projects/output/**/*.lib diff --git a/src/kiwano/base/window.cpp b/src/kiwano/base/window.cpp index 98ef3f6b..bc2a5f80 100644 --- a/src/kiwano/base/window.cpp +++ b/src/kiwano/base/window.cpp @@ -18,8 +18,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -#include "window.h" -#include "logs.h" +#include "Window.h" +#include "Logger.h" #define WINDOW_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX #define WINDOW_FULLSCREEN_STYLE WS_CLIPCHILDREN | WS_POPUP From d34e14b799756e6238873f502a2c9bddb79bc447 Mon Sep 17 00:00:00 2001 From: Nomango <569629550@qq.com> Date: Wed, 14 Aug 2019 23:36:29 +0800 Subject: [PATCH 11/11] update Geometry --- src/kiwano/2d/Actor.cpp | 10 +-- src/kiwano/2d/Actor.h | 8 +- src/kiwano/2d/Canvas.cpp | 2 +- src/kiwano/2d/Canvas.h | 2 +- src/kiwano/2d/ShapeActor.cpp | 12 +-- src/kiwano/2d/action/ActionWalk.cpp | 1 - src/kiwano/math/Matrix.hpp | 70 +++++++-------- src/kiwano/renderer/Geometry.cpp | 132 +++++++++++++++++++++++++--- src/kiwano/renderer/Geometry.h | 72 ++++++++++++++- src/kiwano/renderer/Renderer.cpp | 6 +- src/kiwano/renderer/Renderer.h | 6 +- src/kiwano/renderer/helper.hpp | 8 +- 12 files changed, 249 insertions(+), 80 deletions(-) diff --git a/src/kiwano/2d/Actor.cpp b/src/kiwano/2d/Actor.cpp index b5278b31..2db554b4 100644 --- a/src/kiwano/2d/Actor.cpp +++ b/src/kiwano/2d/Actor.cpp @@ -201,13 +201,13 @@ namespace kiwano EventDispatcher::Dispatch(evt); } - Matrix const & Actor::GetTransformMatrix() const + Matrix3x2 const & Actor::GetTransformMatrix() const { UpdateTransform(); return transform_matrix_; } - Matrix const & Actor::GetTransformInverseMatrix() const + Matrix3x2 const & Actor::GetTransformInverseMatrix() const { UpdateTransform(); if (dirty_transform_inverse_) @@ -228,16 +228,16 @@ namespace kiwano if (is_fast_transform_) { - transform_matrix_ = Matrix::Translation(transform_.position); + transform_matrix_ = Matrix3x2::Translation(transform_.position); } else { // matrix multiplication is optimized by expression template - transform_matrix_ = Matrix::SRT(transform_.position, transform_.scale, transform_.rotation); + transform_matrix_ = Matrix3x2::SRT(transform_.position, transform_.scale, transform_.rotation); if (!transform_.skew.IsOrigin()) { - transform_matrix_ = Matrix::Skewing(transform_.skew) * transform_matrix_; + transform_matrix_ = Matrix3x2::Skewing(transform_.skew) * transform_matrix_; } } diff --git a/src/kiwano/2d/Actor.h b/src/kiwano/2d/Actor.h index d71d5217..55f8f105 100644 --- a/src/kiwano/2d/Actor.h +++ b/src/kiwano/2d/Actor.h @@ -142,10 +142,10 @@ namespace kiwano virtual Rect GetBoundingBox() const; // 获取二维变换矩阵 - Matrix const& GetTransformMatrix() const; + Matrix3x2 const& GetTransformMatrix() const; // 获取二维变换的逆矩阵 - Matrix const& GetTransformInverseMatrix() const; + Matrix3x2 const& GetTransformInverseMatrix() const; // 获取父角色 inline Actor* GetParent() const { return parent_; } @@ -447,8 +447,8 @@ namespace kiwano bool is_fast_transform_; mutable bool dirty_transform_; mutable bool dirty_transform_inverse_; - mutable Matrix transform_matrix_; - mutable Matrix transform_matrix_inverse_; + mutable Matrix3x2 transform_matrix_; + mutable Matrix3x2 transform_matrix_inverse_; }; } diff --git a/src/kiwano/2d/Canvas.cpp b/src/kiwano/2d/Canvas.cpp index 33caed18..c9f01d1b 100644 --- a/src/kiwano/2d/Canvas.cpp +++ b/src/kiwano/2d/Canvas.cpp @@ -161,7 +161,7 @@ namespace kiwano return stroke_width_; } - void Canvas::SetBrushTransform(Matrix const & transform) + void Canvas::SetBrushTransform(Matrix3x2 const & transform) { render_target_->SetTransform(DX::ConvertToMatrix3x2F(transform)); } diff --git a/src/kiwano/2d/Canvas.h b/src/kiwano/2d/Canvas.h index 59fb2b98..add2a2c1 100644 --- a/src/kiwano/2d/Canvas.h +++ b/src/kiwano/2d/Canvas.h @@ -205,7 +205,7 @@ namespace kiwano // 变换画笔 void SetBrushTransform( - Matrix const& transform + Matrix3x2 const& transform ); // 导出为图片 diff --git a/src/kiwano/2d/ShapeActor.cpp b/src/kiwano/2d/ShapeActor.cpp index 9ff124bb..3cab94c1 100644 --- a/src/kiwano/2d/ShapeActor.cpp +++ b/src/kiwano/2d/ShapeActor.cpp @@ -47,7 +47,7 @@ namespace kiwano if (!geo_) return Rect{}; - return geo_.GetBoundingBox(Matrix()); + return geo_.GetBoundingBox(Matrix3x2()); } Rect ShapeActor::GetBoundingBox() const @@ -117,7 +117,7 @@ namespace kiwano void LineActor::SetEndPoint(Point const& end) { - Renderer::GetInstance()->CreateLineGeometry(geo_, Point{}, end); + geo_ = Geometry::CreateLine(Point{}, end); if (geo_) { @@ -145,7 +145,7 @@ namespace kiwano void RectActor::SetRectSize(Size const& size) { - Renderer::GetInstance()->CreateRectGeometry(geo_, Rect{ Point{}, size }); + geo_ = Geometry::CreateRect(Rect{ Point{}, size }); if (geo_) { @@ -183,7 +183,7 @@ namespace kiwano void RoundRectActor::SetRoundedRect(Size const& size, Vec2 const& radius) { - Renderer::GetInstance()->CreateRoundedRectGeometry(geo_, Rect{ Point{}, size }, radius); + geo_ = Geometry::CreateRoundedRect(Rect{ Point{}, size }, radius); if (geo_) { @@ -212,7 +212,7 @@ namespace kiwano void CircleActor::SetRadius(float radius) { - Renderer::GetInstance()->CreateEllipseGeometry(geo_, Point{}, Vec2{ radius, radius }); + geo_ = Geometry::CreateCircle(Point{}, radius); if (geo_) { @@ -240,7 +240,7 @@ namespace kiwano void EllipseActor::SetRadius(Vec2 const& radius) { - Renderer::GetInstance()->CreateEllipseGeometry(geo_, Point{}, radius); + geo_ = Geometry::CreateEllipse(Point{}, radius); if (geo_) { diff --git a/src/kiwano/2d/action/ActionWalk.cpp b/src/kiwano/2d/action/ActionWalk.cpp index addf325e..3a4c77aa 100644 --- a/src/kiwano/2d/action/ActionWalk.cpp +++ b/src/kiwano/2d/action/ActionWalk.cpp @@ -86,7 +86,6 @@ namespace kiwano target->SetRotation(rotation); } } - KGE_LOG(L"%.2f, %.2f", target->GetPositionX(), target->GetPositionY()); } void ActionWalk::BeginPath() diff --git a/src/kiwano/math/Matrix.hpp b/src/kiwano/math/Matrix.hpp index 37d29e06..b13e5391 100644 --- a/src/kiwano/math/Matrix.hpp +++ b/src/kiwano/math/Matrix.hpp @@ -31,7 +31,7 @@ namespace kiwano struct MatrixMultiply; template - struct MatrixT + struct Matrix3x2T { using value_type = _Ty; using vec2_type = Vec2T; @@ -53,25 +53,25 @@ namespace kiwano }; }; - MatrixT() + Matrix3x2T() : _11(1.f), _12(0.f) , _21(0.f), _22(1.f) , _31(0.f), _32(0.f) { } - MatrixT(value_type _11, value_type _12, value_type _21, value_type _22, value_type _31, value_type _32) + Matrix3x2T(value_type _11, value_type _12, value_type _21, value_type _22, value_type _31, value_type _32) : _11(_11), _12(_12), _21(_21), _22(_22), _31(_31), _32(_32) { } - explicit MatrixT(const value_type* p) + explicit Matrix3x2T(const value_type* p) { for (int i = 0; i < 6; i++) m[i] = p[i]; } - MatrixT(MatrixT const& other) + Matrix3x2T(Matrix3x2T const& other) : _11(other._11), _12(other._12) , _21(other._21), _22(other._22) , _31(other._31), _32(other._32) @@ -79,7 +79,7 @@ namespace kiwano } template - MatrixT(_MTy const& other) + Matrix3x2T(_MTy const& other) { for (int i = 0; i < 6; i++) m[i] = other[i]; @@ -95,7 +95,7 @@ namespace kiwano return m[index]; } - inline MatrixT& operator= (MatrixT const& other) + inline Matrix3x2T& operator= (Matrix3x2T const& other) { for (int i = 0; i < 6; i++) m[i] = other[i]; @@ -103,14 +103,14 @@ namespace kiwano } template - inline MatrixT& operator= (MatrixMultiply const& other) + inline Matrix3x2T& operator= (MatrixMultiply const& other) { - MatrixT result(other); + Matrix3x2T result(other); (*this) = result; return (*this); } - inline MatrixT& operator*= (MatrixT const& other) + inline Matrix3x2T& operator*= (Matrix3x2T const& other) { return operator=((*this) * other); } @@ -129,10 +129,10 @@ namespace kiwano _31 == 0.f && _32 == 0.f; } - inline MatrixT Invert() const + inline Matrix3x2T Invert() const { value_type det = 1.f / Determinant(); - return MatrixT( + return Matrix3x2T( det * _22, -det * _12, -det * _21, @@ -181,29 +181,29 @@ namespace kiwano _32 += _12 * v.x + _22 * v.y; } - static inline MatrixT Translation(const vec2_type& v) + static inline Matrix3x2T Translation(const vec2_type& v) { - return MatrixT( + return Matrix3x2T( 1.f, 0.f, 0.f, 1.f, v.x, v.y ); } - static inline MatrixT Scaling(const vec2_type& v) + static inline Matrix3x2T Scaling(const vec2_type& v) { - return MatrixT( + return Matrix3x2T( v.x, 0.f, 0.f, v.y, 0.f, 0.f ); } - static inline MatrixT Scaling( + static inline Matrix3x2T Scaling( const vec2_type& v, const vec2_type& center) { - return MatrixT( + return Matrix3x2T( v.x, 0.f, 0.f, v.y, center.x - v.x * center.x, @@ -211,24 +211,24 @@ namespace kiwano ); } - static inline MatrixT Rotation(value_type angle) + static inline Matrix3x2T Rotation(value_type angle) { value_type s = math::Sin(angle); value_type c = math::Cos(angle); - return MatrixT( + return Matrix3x2T( c, s, -s, c, 0.f, 0.f ); } - static inline MatrixT Rotation( + static inline Matrix3x2T Rotation( value_type angle, const vec2_type& center) { value_type s = math::Sin(angle); value_type c = math::Cos(angle); - return MatrixT( + return Matrix3x2T( c, s, -s, c, center.x * (1 - c) + center.y * s, @@ -236,35 +236,35 @@ namespace kiwano ); } - static inline MatrixT SRT(const vec2_type& trans, const vec2_type& scale, value_type angle) + static inline Matrix3x2T SRT(const vec2_type& trans, const vec2_type& scale, value_type angle) { value_type s = math::Sin(angle); value_type c = math::Cos(angle); - return MatrixT( + return Matrix3x2T( c * scale.x, s * scale.x, -s * scale.y, c * scale.y, trans.x, trans.y ); } - static inline MatrixT Skewing(const vec2_type& angle) + static inline Matrix3x2T Skewing(const vec2_type& angle) { value_type tx = math::Tan(angle.x); value_type ty = math::Tan(angle.y); - return MatrixT( + return Matrix3x2T( 1.f, -ty, -tx, 1.f, 0.f, 0.f ); } - static inline MatrixT Skewing( + static inline Matrix3x2T Skewing( const vec2_type& angle, const vec2_type& center) { value_type tx = math::Tan(angle.x); value_type ty = math::Tan(angle.y); - return MatrixT( + return Matrix3x2T( 1.f, -ty, -tx, 1.f, center.y * tx, center.x * ty @@ -309,23 +309,23 @@ namespace kiwano template inline - MatrixMultiply<_Ty, MatrixT<_Ty>, MatrixT<_Ty>> - operator *(MatrixT<_Ty> const& lhs, MatrixT<_Ty> const& rhs) + MatrixMultiply<_Ty, Matrix3x2T<_Ty>, Matrix3x2T<_Ty>> + operator *(Matrix3x2T<_Ty> const& lhs, Matrix3x2T<_Ty> const& rhs) { - return MatrixMultiply<_Ty, MatrixT<_Ty>, MatrixT<_Ty>>(lhs, rhs); + return MatrixMultiply<_Ty, Matrix3x2T<_Ty>, Matrix3x2T<_Ty>>(lhs, rhs); } template inline - MatrixMultiply<_Ty, MatrixMultiply<_Ty, _Lty, _Rty>, MatrixT<_Ty>> - operator *(MatrixMultiply<_Ty, _Lty, _Rty> const& lhs, MatrixT<_Ty> const& rhs) + MatrixMultiply<_Ty, MatrixMultiply<_Ty, _Lty, _Rty>, Matrix3x2T<_Ty>> + operator *(MatrixMultiply<_Ty, _Lty, _Rty> const& lhs, Matrix3x2T<_Ty> const& rhs) { - return MatrixMultiply<_Ty, MatrixMultiply<_Ty, _Lty, _Rty>, MatrixT<_Ty>>(lhs, rhs); + return MatrixMultiply<_Ty, MatrixMultiply<_Ty, _Lty, _Rty>, Matrix3x2T<_Ty>>(lhs, rhs); } } } namespace kiwano { - using Matrix = kiwano::math::MatrixT; + using Matrix3x2 = kiwano::math::Matrix3x2T; } diff --git a/src/kiwano/renderer/Geometry.cpp b/src/kiwano/renderer/Geometry.cpp index 9d5ada2e..f56de2ce 100644 --- a/src/kiwano/renderer/Geometry.cpp +++ b/src/kiwano/renderer/Geometry.cpp @@ -38,7 +38,7 @@ namespace kiwano { } - Rect Geometry::GetBoundingBox(Matrix const& transform) const + Rect Geometry::GetBoundingBox(Matrix3x2 const& transform) const { if (!geo_) return Rect{}; @@ -76,6 +76,59 @@ namespace kiwano return false; } + Geometry Geometry::CombineWith(Geometry input, CombineMode mode, Matrix3x2 const& input_matrix) + { + if (geo_ && input.geo_) + { + GeometrySink sink; + sink.Init(); + sink.OpenSink(); + + ThrowIfFailed( + geo_->CombineWithGeometry( + input.geo_.get(), + D2D1_COMBINE_MODE(mode), + DX::ConvertToMatrix3x2F(input_matrix), + sink.GetGeometrySink().get() + ) + ); + + sink.CloseSink(); + return sink.GetGeometry(); + } + return Geometry(); + } + + Geometry Geometry::Combine(Vector const& geos, Vector const& modes, Vector const& matrixs) + { + if ((geos.size() == (modes.size() + 1) || modes.size() == 1) + && (geos.size() == (matrixs.size() + 1) || matrixs.size() == 1)) + { + GeometrySink sink; + sink.Init(); + sink.OpenSink(); + + for (size_t i = 0; i < geos.size() - 1; i++) + { + CombineMode mode = (modes.size() == 1) ? modes[0] : modes[i]; + const Matrix3x2& matrix = (matrixs.size() == 1) ? matrixs[0] : matrixs[i]; + + ThrowIfFailed( + geos[i].geo_->CombineWithGeometry( + geos[i + 1].geo_.get(), + D2D1_COMBINE_MODE(mode), + DX::ConvertToMatrix3x2F(matrix), + sink.GetGeometrySink().get() + ) + ); + } + + sink.CloseSink(); + return sink.GetGeometry(); + } + return Geometry(); + } + float Geometry::ComputeArea() { if (!geo_) @@ -102,6 +155,41 @@ namespace kiwano return !!ret; } + Geometry Geometry::CreateLine(Point const& begin, Point const& end) + { + Geometry output; + Renderer::GetInstance()->CreateLineGeometry(output, begin, end); + return output; + } + + Geometry Geometry::CreateRect(Rect const& rect) + { + Geometry output; + Renderer::GetInstance()->CreateRectGeometry(output, rect); + return output; + } + + Geometry Geometry::CreateRoundedRect(Rect const& rect, Vec2 const& radius) + { + Geometry output; + Renderer::GetInstance()->CreateRoundedRectGeometry(output, rect, radius); + return output; + } + + Geometry Geometry::CreateCircle(Point const& center, float radius) + { + Geometry output; + Renderer::GetInstance()->CreateEllipseGeometry(output, center, Vec2{ radius, radius }); + return output; + } + + Geometry Geometry::CreateEllipse(Point const& center, Vec2 const& radius) + { + Geometry output; + Renderer::GetInstance()->CreateEllipseGeometry(output, center, radius); + return output; + } + // // GeometrySink // @@ -112,20 +200,14 @@ namespace kiwano GeometrySink& GeometrySink::BeginPath(Point const& begin_pos) { - if (!path_geo_) - { - Renderer::GetInstance()->CreatePathGeometrySink(*this); - } + Init(); if (!sink_) { - ThrowIfFailed(path_geo_->Open(&sink_)); + OpenSink(); } - if (sink_) - { - sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); - } + sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); return (*this); } @@ -135,9 +217,7 @@ namespace kiwano { sink_->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN); - ThrowIfFailed(sink_->Close()); - - sink_ = nullptr; + CloseSink(); } return (*this); } @@ -200,4 +280,30 @@ namespace kiwano return Geometry(path_geo_); } + void GeometrySink::Init() + { + if (!path_geo_) + { + Renderer::GetInstance()->CreatePathGeometrySink(*this); + } + } + + void GeometrySink::OpenSink() + { + if (!sink_) + { + ThrowIfFailed(path_geo_->Open(&sink_)); + } + } + + void GeometrySink::CloseSink() + { + if (sink_) + { + ThrowIfFailed(sink_->Close()); + + sink_ = nullptr; + } + } + } diff --git a/src/kiwano/renderer/Geometry.h b/src/kiwano/renderer/Geometry.h index 0217dde9..8a4f5417 100644 --- a/src/kiwano/renderer/Geometry.h +++ b/src/kiwano/renderer/Geometry.h @@ -24,13 +24,28 @@ namespace kiwano { + // 几何体 class KGE_API Geometry { public: + // 几何体组合模式 + enum class CombineMode + { + Union, /* 并集 (A + B) */ + Intersect, /* 交集 (A + B) */ + Xor, /* 对称差集 ((A - B) + (B - A)) */ + Exclude /* 差集 (A - B) */ + }; + + public: + Geometry(); + + Geometry(ComPtr geo); + // 获取外切包围盒 Rect GetBoundingBox( - Matrix const& transform = Matrix() + Matrix3x2 const& transform = Matrix3x2() ) const; // 判断图形是否包含点 @@ -51,10 +66,49 @@ namespace kiwano Vec2& tangent ); - public: - Geometry(); + // 组合几何体 + Geometry CombineWith( + Geometry input, + CombineMode mode, + Matrix3x2 const& input_matrix = Matrix3x2() + ); - Geometry(ComPtr geo); + // 组合多个几何体 + // 参数 modes 和 matrixs 的数量应为 1 或 geos 的数量减一 + static Geometry Combine( + Vector const& geos, + Vector const& modes, + Vector const& matrixs = { Matrix3x2() } + ); + + // 创建直线 + static Geometry CreateLine( + Point const& begin, + Point const& end + ); + + // 创建矩形 + static Geometry CreateRect( + Rect const& rect + ); + + // 创建圆角矩形 + static Geometry CreateRoundedRect( + Rect const& rect, + Vec2 const& radius + ); + + // 创建圆形 + static Geometry CreateCircle( + Point const& center, + float radius + ); + + // 创建椭圆形 + static Geometry CreateEllipse( + Point const& center, + Vec2 const& radius + ); public: inline ComPtr GetGeometry() const { return geo_; } @@ -119,6 +173,16 @@ namespace kiwano inline void SetPathGeometry(ComPtr path) { path_geo_ = path; } + inline ComPtr GetGeometrySink() const { return sink_; } + + inline void SetGeometrySink(ComPtr sink) { sink_ = sink; } + + void Init(); + + void OpenSink(); + + void CloseSink(); + protected: ComPtr path_geo_; ComPtr sink_; diff --git a/src/kiwano/renderer/Renderer.cpp b/src/kiwano/renderer/Renderer.cpp index 9cfe13b1..77361827 100644 --- a/src/kiwano/renderer/Renderer.cpp +++ b/src/kiwano/renderer/Renderer.cpp @@ -523,7 +523,7 @@ namespace kiwano vsync_ = enabled; } - void Renderer::PushClip(const Matrix & clip_matrix, const Size & clip_size) + void Renderer::PushClip(const Matrix3x2 & clip_matrix, const Size & clip_size) { HRESULT hr = S_OK; if (!device_context_) @@ -630,7 +630,7 @@ namespace kiwano clear_color_ = color; } - void Renderer::SetTransform(const Matrix & matrix) + void Renderer::SetTransform(const Matrix3x2 & matrix) { HRESULT hr = S_OK; if (!device_context_) @@ -750,7 +750,7 @@ namespace kiwano ThrowIfFailed(hr); } - bool Renderer::CheckVisibility(Size const& content_size, Matrix const& transform) + bool Renderer::CheckVisibility(Size const& content_size, Matrix3x2 const& transform) { return Rect{ Point{}, output_size_ }.Intersects( transform.Transform(Rect{ Point{}, content_size }) diff --git a/src/kiwano/renderer/Renderer.h b/src/kiwano/renderer/Renderer.h index 50c9373c..a365a6cb 100644 --- a/src/kiwano/renderer/Renderer.h +++ b/src/kiwano/renderer/Renderer.h @@ -143,7 +143,7 @@ namespace kiwano ); void SetTransform( - const Matrix& matrix + const Matrix3x2& matrix ); void SetTextStyle( @@ -156,7 +156,7 @@ namespace kiwano ); void PushClip( - const Matrix& clip_matrix, + const Matrix3x2& clip_matrix, const Size& clip_size ); @@ -176,7 +176,7 @@ namespace kiwano bool CheckVisibility( Size const& content_size, - Matrix const& transform + Matrix3x2 const& transform ); public: diff --git a/src/kiwano/renderer/helper.hpp b/src/kiwano/renderer/helper.hpp index 35e05973..3c781b1b 100644 --- a/src/kiwano/renderer/helper.hpp +++ b/src/kiwano/renderer/helper.hpp @@ -122,22 +122,22 @@ namespace kiwano // SizeF // - inline D2D1_MATRIX_3X2_F const& ConvertToMatrix3x2F(Matrix const& matrix) + inline D2D1_MATRIX_3X2_F const& ConvertToMatrix3x2F(Matrix3x2 const& matrix) { return reinterpret_cast(matrix); } - inline D2D1_MATRIX_3X2_F& ConvertToMatrix3x2F(Matrix& matrix) + inline D2D1_MATRIX_3X2_F& ConvertToMatrix3x2F(Matrix3x2& matrix) { return reinterpret_cast(matrix); } - inline const D2D1_MATRIX_3X2_F* ConvertToMatrix3x2F(const Matrix* matrix) + inline const D2D1_MATRIX_3X2_F* ConvertToMatrix3x2F(const Matrix3x2* matrix) { return reinterpret_cast(matrix); } - inline D2D1_MATRIX_3X2_F* ConvertToMatrix3x2F(Matrix* matrix) + inline D2D1_MATRIX_3X2_F* ConvertToMatrix3x2F(Matrix3x2* matrix) { return reinterpret_cast(matrix); }