From ab50ec78b63d1ae2100551efeec14ec5d6ea59c0 Mon Sep 17 00:00:00 2001 From: Nomango Date: Fri, 27 Dec 2019 10:51:34 +0800 Subject: [PATCH] Update RenderTarget --- src/kiwano/2d/Canvas.cpp | 74 ++++++++++++++-------------- src/kiwano/2d/Canvas.h | 18 +++---- src/kiwano/2d/GifSprite.cpp | 49 +++++++++--------- src/kiwano/2d/GifSprite.h | 24 ++++----- src/kiwano/2d/ShapeActor.cpp | 8 +-- src/kiwano/2d/action/ActionWalk.cpp | 4 +- src/kiwano/renderer/Brush.h | 49 +++++++----------- src/kiwano/renderer/Font.cpp | 10 ---- src/kiwano/renderer/Font.h | 4 -- src/kiwano/renderer/Geometry.cpp | 17 ++++--- src/kiwano/renderer/Geometry.h | 40 +++++++++------ src/kiwano/renderer/GifImage.cpp | 11 ----- src/kiwano/renderer/GifImage.h | 10 ++-- src/kiwano/renderer/LayerArea.h | 6 ++- src/kiwano/renderer/RenderTarget.cpp | 43 +++++++++++----- src/kiwano/renderer/RenderTarget.h | 59 +++++++++++++++++----- src/kiwano/renderer/Renderer.cpp | 22 +++++++-- src/kiwano/renderer/Renderer.h | 4 +- src/kiwano/renderer/TextLayout.h | 8 ++- src/kiwano/renderer/Texture.cpp | 18 ------- src/kiwano/renderer/Texture.h | 28 +++++------ 21 files changed, 268 insertions(+), 238 deletions(-) diff --git a/src/kiwano/2d/Canvas.cpp b/src/kiwano/2d/Canvas.cpp index fa30f137..545f0929 100644 --- a/src/kiwano/2d/Canvas.cpp +++ b/src/kiwano/2d/Canvas.cpp @@ -40,12 +40,12 @@ namespace kiwano void Canvas::BeginDraw() { - rt_.BeginDraw(); + rt_->BeginDraw(); } void Canvas::EndDraw() { - rt_.EndDraw(); + rt_->EndDraw(); cache_expired_ = true; } @@ -89,7 +89,7 @@ namespace kiwano void Canvas::SetBrushOpacity(float opacity) { - rt_.SetOpacity(opacity); + rt_->SetOpacity(opacity); } Color Canvas::GetStrokeColor() const @@ -109,43 +109,43 @@ namespace kiwano float Canvas::GetBrushOpacity() const { - return rt_.GetOpacity(); + return rt_->GetOpacity(); } void Canvas::SetBrushTransform(Transform const& transform) { - rt_.SetTransform(transform.ToMatrix()); + rt_->SetTransform(transform.ToMatrix()); } void Canvas::SetBrushTransform(Matrix3x2 const & transform) { - rt_.SetTransform(transform); + rt_->SetTransform(transform); } void Canvas::PushLayerArea(LayerArea& area) { - rt_.PushLayer(area); + rt_->PushLayer(area); } void Canvas::PopLayerArea() { - rt_.PopLayer(); + rt_->PopLayer(); } void Canvas::PushClipRect(Rect const& clip_rect) { - rt_.PushClipRect(clip_rect); + rt_->PushClipRect(clip_rect); } void Canvas::PopClipRect() { - rt_.PopClipRect(); + rt_->PopClipRect(); } void Canvas::DrawLine(Point const& begin, Point const& end) { - rt_.SetDefaultBrushColor(stroke_color_); - rt_.DrawLine( + rt_->SetDefaultBrushColor(stroke_color_); + rt_->DrawLine( begin, end, stroke_width_, @@ -156,8 +156,8 @@ namespace kiwano void Canvas::DrawCircle(Point const& center, float radius) { - rt_.SetDefaultBrushColor(stroke_color_); - rt_.DrawEllipse( + rt_->SetDefaultBrushColor(stroke_color_); + rt_->DrawEllipse( center, Vec2(radius, radius), stroke_width_, @@ -168,8 +168,8 @@ namespace kiwano void Canvas::DrawEllipse(Point const& center, Vec2 const& radius) { - rt_.SetDefaultBrushColor(stroke_color_); - rt_.DrawEllipse( + rt_->SetDefaultBrushColor(stroke_color_); + rt_->DrawEllipse( center, radius, stroke_width_, @@ -180,8 +180,8 @@ namespace kiwano void Canvas::DrawRect(Rect const& rect) { - rt_.SetDefaultBrushColor(stroke_color_); - rt_.DrawRectangle( + rt_->SetDefaultBrushColor(stroke_color_); + rt_->DrawRectangle( rect, stroke_width_, stroke_style_ @@ -191,8 +191,8 @@ namespace kiwano void Canvas::DrawRoundedRect(Rect const& rect, Vec2 const& radius) { - rt_.SetDefaultBrushColor(stroke_color_); - rt_.DrawRoundedRectangle( + rt_->SetDefaultBrushColor(stroke_color_); + rt_->DrawRoundedRectangle( rect, radius, stroke_width_, @@ -203,8 +203,8 @@ namespace kiwano void Canvas::FillCircle(Point const& center, float radius) { - rt_.SetDefaultBrushColor(fill_color_); - rt_.FillEllipse( + rt_->SetDefaultBrushColor(fill_color_); + rt_->FillEllipse( center, Vec2(radius, radius) ); @@ -213,8 +213,8 @@ namespace kiwano void Canvas::FillEllipse(Point const& center, Vec2 const& radius) { - rt_.SetDefaultBrushColor(fill_color_); - rt_.FillEllipse( + rt_->SetDefaultBrushColor(fill_color_); + rt_->FillEllipse( center, radius ); @@ -223,8 +223,8 @@ namespace kiwano void Canvas::FillRect(Rect const& rect) { - rt_.SetDefaultBrushColor(fill_color_); - rt_.FillRectangle( + rt_->SetDefaultBrushColor(fill_color_); + rt_->FillRectangle( rect ); cache_expired_ = true; @@ -232,8 +232,8 @@ namespace kiwano void Canvas::FillRoundedRect(Rect const& rect, Vec2 const& radius) { - rt_.SetDefaultBrushColor(fill_color_); - rt_.FillRoundedRectangle( + rt_->SetDefaultBrushColor(fill_color_); + rt_->FillRoundedRectangle( rect, radius ); @@ -244,7 +244,7 @@ namespace kiwano { if (texture) { - rt_.DrawTexture(*texture, src_rect, dest_rect); + rt_->DrawTexture(*texture, src_rect, dest_rect); cache_expired_ = true; } } @@ -262,7 +262,7 @@ namespace kiwano void Canvas::DrawTextLayout(TextLayout const& layout, Point const& point) { - rt_.DrawTextLayout(layout, point); + rt_->DrawTextLayout(layout, point); } void Canvas::BeginPath(Point const& begin_pos) @@ -297,8 +297,8 @@ namespace kiwano void Canvas::StrokePath() { - rt_.SetDefaultBrushColor(stroke_color_); - rt_.DrawGeometry( + rt_->SetDefaultBrushColor(stroke_color_); + rt_->DrawGeometry( geo_sink_.GetGeometry(), stroke_width_, stroke_style_ @@ -308,8 +308,8 @@ namespace kiwano void Canvas::FillPath() { - rt_.SetDefaultBrushColor(fill_color_); - rt_.FillGeometry( + rt_->SetDefaultBrushColor(fill_color_); + rt_->FillGeometry( geo_sink_.GetGeometry() ); cache_expired_ = true; @@ -317,13 +317,13 @@ namespace kiwano void Canvas::Clear() { - rt_.Clear(); + rt_->Clear(); cache_expired_ = true; } void Canvas::Clear(Color const& clear_color) { - rt_.Clear(clear_color); + rt_->Clear(clear_color); cache_expired_ = true; } @@ -337,7 +337,7 @@ namespace kiwano { if (cache_expired_) { - texture_cached_ = rt_.GetOutput(); + texture_cached_ = rt_->GetOutput(); cache_expired_ = false; } } diff --git a/src/kiwano/2d/Canvas.h b/src/kiwano/2d/Canvas.h index 447a5013..b7c848d8 100644 --- a/src/kiwano/2d/Canvas.h +++ b/src/kiwano/2d/Canvas.h @@ -262,16 +262,16 @@ namespace kiwano void UpdateCache() const; private: - float stroke_width_; - Color fill_color_; - Color stroke_color_; - TextStyle text_style_; - StrokeStyle stroke_style_; - GeometrySink geo_sink_; + float stroke_width_; + Color fill_color_; + Color stroke_color_; + TextStyle text_style_; + StrokeStyle stroke_style_; + GeometrySink geo_sink_; + TextureRenderTargetPtr rt_; - mutable bool cache_expired_; - mutable TexturePtr texture_cached_; - mutable TextureRenderTarget rt_; + mutable bool cache_expired_; + mutable TexturePtr texture_cached_; }; /** @} */ diff --git a/src/kiwano/2d/GifSprite.cpp b/src/kiwano/2d/GifSprite.cpp index 69657b73..39bbfd26 100644 --- a/src/kiwano/2d/GifSprite.cpp +++ b/src/kiwano/2d/GifSprite.cpp @@ -73,7 +73,7 @@ namespace kiwano SetSize(Size{ static_cast(gif_->GetWidthInPixels()), static_cast(gif_->GetHeightInPixels()) }); - if (!frame_rt_.IsValid()) + if (!frame_rt_) { Renderer::instance().CreateTextureRenderTarget(frame_rt_); } @@ -129,9 +129,10 @@ namespace kiwano void GifSprite::ComposeNextFrame() { - KGE_ASSERT(gif_ && gif_->IsValid()); + KGE_ASSERT(frame_rt_); + KGE_ASSERT(gif_); - if (frame_rt_.IsValid()) + if (frame_rt_->IsValid()) { do { @@ -170,6 +171,7 @@ namespace kiwano void GifSprite::OverlayNextFrame() { + KGE_ASSERT(frame_rt_); KGE_ASSERT(gif_ && gif_->IsValid()); frame_ = gif_->GetFrame(next_index_); @@ -179,9 +181,9 @@ namespace kiwano SaveComposedFrame(); } - if (frame_rt_.IsValid()) + if (frame_rt_->IsValid()) { - frame_rt_.BeginDraw(); + frame_rt_->BeginDraw(); if (next_index_ == 0) { @@ -190,12 +192,12 @@ namespace kiwano if (frame_.raw) { - frame_rt_.DrawTexture(*frame_.raw, nullptr, &frame_.rect); + frame_rt_->DrawTexture(*frame_.raw, nullptr, &frame_.rect); } - frame_rt_.EndDraw(); + frame_rt_->EndDraw(); - frame_to_render_ = frame_rt_.GetOutput(); + frame_to_render_ = frame_rt_->GetOutput(); if (frame_to_render_) { next_index_ = (++next_index_) % gif_->GetFramesCount(); @@ -215,7 +217,8 @@ namespace kiwano void GifSprite::SaveComposedFrame() { - TexturePtr frame_to_be_saved = frame_rt_.GetOutput(); + KGE_ASSERT(frame_rt_); + TexturePtr frame_to_be_saved = frame_rt_->GetOutput(); HRESULT hr = frame_to_be_saved ? S_OK : E_FAIL; @@ -223,17 +226,11 @@ namespace kiwano { if (!saved_frame_) { - auto size = frame_to_be_saved->GetSizeInPixels(); - auto prop = D2D1::BitmapProperties(frame_to_be_saved->GetPixelFormat()); - - ComPtr saved_bitmap; - hr = frame_rt_.GetRenderTarget()->CreateBitmap(D2D1::SizeU(size.x, size.y), prop, &saved_bitmap); - - if (SUCCEEDED(hr)) - { - saved_frame_->SetBitmap(saved_bitmap); - } + saved_frame_ = new Texture; + frame_rt_->CreateTexture(*saved_frame_, frame_to_be_saved->GetSizeInPixels(), frame_to_be_saved->GetPixelFormat()); } + + hr = saved_frame_ ? S_OK : E_FAIL; } if (SUCCEEDED(hr)) @@ -246,11 +243,12 @@ namespace kiwano void GifSprite::RestoreSavedFrame() { + KGE_ASSERT(frame_rt_); HRESULT hr = saved_frame_ ? S_OK : E_FAIL; if (SUCCEEDED(hr)) { - TexturePtr frame_to_copy_to = frame_rt_.GetOutput(); + TexturePtr frame_to_copy_to = frame_rt_->GetOutput(); hr = frame_to_copy_to ? S_OK : E_FAIL; @@ -265,13 +263,14 @@ namespace kiwano void GifSprite::ClearCurrentFrameArea() { - frame_rt_.BeginDraw(); + KGE_ASSERT(frame_rt_); + frame_rt_->BeginDraw(); - frame_rt_.PushClipRect(frame_.rect); - frame_rt_.Clear(); - frame_rt_.PopClipRect(); + frame_rt_->PushClipRect(frame_.rect); + frame_rt_->Clear(); + frame_rt_->PopClipRect(); - return frame_rt_.EndDraw(); + return frame_rt_->EndDraw(); } } diff --git a/src/kiwano/2d/GifSprite.h b/src/kiwano/2d/GifSprite.h index 611473c9..3da88764 100644 --- a/src/kiwano/2d/GifSprite.h +++ b/src/kiwano/2d/GifSprite.h @@ -151,18 +151,18 @@ namespace kiwano void ClearCurrentFrameArea(); private: - bool animating_; - int total_loop_count_; - int loop_count_; - size_t next_index_; - Duration frame_elapsed_; - LoopDoneCallback loop_cb_; - DoneCallback done_cb_; - GifImagePtr gif_; - GifImage::Frame frame_; - TexturePtr saved_frame_; - TexturePtr frame_to_render_; - TextureRenderTarget frame_rt_; + bool animating_; + int total_loop_count_; + int loop_count_; + size_t next_index_; + Duration frame_elapsed_; + LoopDoneCallback loop_cb_; + DoneCallback done_cb_; + GifImagePtr gif_; + GifImage::Frame frame_; + TexturePtr saved_frame_; + TexturePtr frame_to_render_; + TextureRenderTargetPtr frame_rt_; }; /** @} */ diff --git a/src/kiwano/2d/ShapeActor.cpp b/src/kiwano/2d/ShapeActor.cpp index 2dd3000f..dd90f5b7 100644 --- a/src/kiwano/2d/ShapeActor.cpp +++ b/src/kiwano/2d/ShapeActor.cpp @@ -49,7 +49,7 @@ namespace kiwano Rect ShapeActor::GetBoundingBox() const { - if (!geo_) + if (!geo_.IsValid()) return Rect{}; return geo_.GetBoundingBox(GetTransformMatrix()); @@ -83,7 +83,7 @@ namespace kiwano void ShapeActor::SetGeometry(Geometry const& geometry) { geo_ = geometry; - if (geo_) + if (geo_.IsValid()) { bounds_ = geo_.GetBoundingBox(); SetSize(bounds_.GetSize()); @@ -97,7 +97,7 @@ namespace kiwano void ShapeActor::OnRender(RenderTarget* rt) { - if (geo_ && CheckVisibilty(rt)) + if (geo_.IsValid() && CheckVisibilty(rt)) { PrepareRender(rt); @@ -317,7 +317,7 @@ namespace kiwano sink_.EndPath(closed); Geometry geo = sink_.GetGeometry(); - if (geo) + if (geo.IsValid()) { SetGeometry(geo); } diff --git a/src/kiwano/2d/action/ActionWalk.cpp b/src/kiwano/2d/action/ActionWalk.cpp index 16719996..be88b2b1 100644 --- a/src/kiwano/2d/action/ActionWalk.cpp +++ b/src/kiwano/2d/action/ActionWalk.cpp @@ -60,7 +60,7 @@ namespace kiwano void ActionWalk::Init(Actor* target) { - if (!path_) + if (!path_.IsValid()) { Done(); return; @@ -121,7 +121,7 @@ namespace kiwano void ActionWalk::ClearPath() { - path_.SetGeometry(nullptr); + path_.Clear(); } } diff --git a/src/kiwano/renderer/Brush.h b/src/kiwano/renderer/Brush.h index 3ff00f63..4941152b 100644 --- a/src/kiwano/renderer/Brush.h +++ b/src/kiwano/renderer/Brush.h @@ -90,48 +90,32 @@ namespace kiwano ); }; - // 画笔 + /** + * \~chinese + * @brief 画刷 + */ class KGE_API Brush { public: Brush(); - Brush( - Color const& color - ); + Brush(Color const& color); - Brush( - SolidColorStyle const& style - ); + Brush(SolidColorStyle const& style); - Brush( - LinearGradientStyle const& style - ); + Brush(LinearGradientStyle const& style); - Brush( - RadialGradientStyle const& style - ); + Brush(RadialGradientStyle const& style); bool IsValid() const; - inline void SetColor( - Color const& color - ) - { - SetStyle(SolidColorStyle{ color }); - } + void SetColor(Color const& color); - void SetStyle( - SolidColorStyle const& style - ); + void SetStyle(SolidColorStyle const& style); - void SetStyle( - LinearGradientStyle const& style - ); + void SetStyle(LinearGradientStyle const& style); - void SetStyle( - RadialGradientStyle const& style - ); + void SetStyle(RadialGradientStyle const& style); float GetOpacity() const; @@ -149,9 +133,7 @@ namespace kiwano Type GetType() const { return type_; } public: - Brush( - ComPtr brush - ); + Brush(ComPtr brush); void SetBrush(ComPtr const& brush); @@ -163,4 +145,9 @@ namespace kiwano ComPtr raw_; }; + inline void Brush::SetColor(Color const& color) + { + SetStyle(SolidColorStyle{ color }); + } + } diff --git a/src/kiwano/renderer/Font.cpp b/src/kiwano/renderer/Font.cpp index 46fe442b..69b17105 100644 --- a/src/kiwano/renderer/Font.cpp +++ b/src/kiwano/renderer/Font.cpp @@ -27,16 +27,6 @@ namespace kiwano { } - Font::Font(String const& font_file) - { - Load(font_file); - } - - Font::Font(Resource const& font_resource) - { - Load(font_resource); - } - bool Font::Load(String const& font_file) { try diff --git a/src/kiwano/renderer/Font.h b/src/kiwano/renderer/Font.h index 8e916b92..e7a360a0 100644 --- a/src/kiwano/renderer/Font.h +++ b/src/kiwano/renderer/Font.h @@ -39,10 +39,6 @@ namespace kiwano public: Font(); - Font(String const& font_file); - - Font(Resource const& font_resource); - bool Load(String const& font_file); bool Load(Resource const& font_resource); diff --git a/src/kiwano/renderer/Geometry.cpp b/src/kiwano/renderer/Geometry.cpp index 9a6a46c5..d04418f2 100644 --- a/src/kiwano/renderer/Geometry.cpp +++ b/src/kiwano/renderer/Geometry.cpp @@ -33,11 +33,6 @@ namespace kiwano { } - Geometry::Geometry(ComPtr geo) - : geo_(geo) - { - } - bool Geometry::IsValid() const { return geo_ != nullptr; @@ -92,6 +87,11 @@ namespace kiwano return false; } + void Geometry::Clear() + { + geo_.reset(); + } + void Geometry::CombineWith(GeometrySink& sink, Geometry input, CombineMode mode, Matrix3x2 const& input_matrix) const { if (geo_ && input.geo_) @@ -277,14 +277,17 @@ namespace kiwano { EndPath(); } - return Geometry(path_geo_); + + Geometry geo; + geo.SetGeometry(path_geo_); + return geo; } void GeometrySink::Init() { if (!path_geo_) { - Renderer::instance().CreatePathGeometrySink(*this); + Renderer::instance().CreateGeometrySink(*this); } } diff --git a/src/kiwano/renderer/Geometry.h b/src/kiwano/renderer/Geometry.h index b9a3dc95..05b56859 100644 --- a/src/kiwano/renderer/Geometry.h +++ b/src/kiwano/renderer/Geometry.h @@ -23,26 +23,20 @@ namespace kiwano { + class RenderTarget; + class Renderer; class GeometrySink; // 几何体 class KGE_API Geometry { - public: - // 几何体组合模式 - enum class CombineMode - { - Union, /* 并集 (A + B) */ - Intersect, /* 交集 (A + B) */ - Xor, /* 对称差集 ((A - B) + (B - A)) */ - Exclude /* 差集 (A - B) */ - }; + friend class RenderTarget; + friend class Renderer; + friend class GeometrySink; public: Geometry(); - Geometry(ComPtr geo); - bool IsValid() const; // 获取外切包围盒 @@ -72,6 +66,19 @@ namespace kiwano Vec2& tangent ) const; + // 清除形状 + void Clear(); + + public: + // 几何体组合模式 + enum class CombineMode + { + Union, /* 并集 (A + B) */ + Intersect, /* 交集 (A + B) */ + Xor, /* 对称差集 ((A - B) + (B - A)) */ + Exclude /* 差集 (A - B) */ + }; + // 组合几何体 void CombineWith( GeometrySink& sink, @@ -87,6 +94,7 @@ namespace kiwano Matrix3x2 const& input_matrix = Matrix3x2() ) const; + public: // 创建直线 static Geometry CreateLine( Point const& begin, @@ -116,13 +124,11 @@ namespace kiwano Vec2 const& radius ); - public: + private: inline ComPtr GetGeometry() const { return geo_; } inline void SetGeometry(ComPtr geometry) { geo_ = geometry; } - inline operator bool() const { return IsValid(); } - private: ComPtr geo_; }; @@ -132,8 +138,12 @@ namespace kiwano class KGE_API GeometrySink : protected Noncopyable { + friend class Geometry; + friend class Renderer; + public: GeometrySink(); + ~GeometrySink(); // 开始添加路径 @@ -187,7 +197,7 @@ namespace kiwano // 关闭流 void Close(); - public: + private: inline ComPtr GetPathGeometry() const { return path_geo_; } inline void SetPathGeometry(ComPtr path) { path_geo_ = path; } diff --git a/src/kiwano/renderer/GifImage.cpp b/src/kiwano/renderer/GifImage.cpp index 53d0c478..2d8a6298 100644 --- a/src/kiwano/renderer/GifImage.cpp +++ b/src/kiwano/renderer/GifImage.cpp @@ -31,17 +31,6 @@ namespace kiwano { } - GifImage::GifImage(String const& file_path) - { - Load(file_path); - } - - GifImage::GifImage(Resource const& res) - : GifImage() - { - Load(res); - } - bool GifImage::Load(String const& file_path) { Renderer::instance().CreateGifImage(*this, file_path); diff --git a/src/kiwano/renderer/GifImage.h b/src/kiwano/renderer/GifImage.h index b56513f4..7ef3056a 100644 --- a/src/kiwano/renderer/GifImage.h +++ b/src/kiwano/renderer/GifImage.h @@ -24,19 +24,19 @@ namespace kiwano { + class Renderer; + KGE_DECLARE_SMART_PTR(GifImage); // GIF 图像 class KGE_API GifImage : public ObjectBase { + friend class Renderer; + public: GifImage(); - GifImage(String const& file_path); - - GifImage(Resource const& res); - bool Load(String const& file_path); bool Load(Resource const& res); @@ -70,11 +70,11 @@ namespace kiwano Frame GetFrame(uint32_t index); + private: ComPtr GetDecoder() const; void SetDecoder(ComPtr decoder); - private: HRESULT GetGlobalMetadata(); private: diff --git a/src/kiwano/renderer/LayerArea.h b/src/kiwano/renderer/LayerArea.h index aec21f2b..cad91950 100644 --- a/src/kiwano/renderer/LayerArea.h +++ b/src/kiwano/renderer/LayerArea.h @@ -23,9 +23,13 @@ namespace kiwano { + class RenderTarget; + // 图层 class KGE_API LayerArea { + friend class RenderTarget; + public: LayerArea(); @@ -53,7 +57,7 @@ namespace kiwano // 设置几何蒙层变换 inline void SetMaskTransform(Matrix3x2 const& matrix) { mask_transform_ = matrix; } - public: + private: inline ComPtr GetLayer() const { return layer_; } inline void SetLayer(ComPtr layer) { layer_ = layer; } diff --git a/src/kiwano/renderer/RenderTarget.cpp b/src/kiwano/renderer/RenderTarget.cpp index 3a08161d..4319b9d2 100644 --- a/src/kiwano/renderer/RenderTarget.cpp +++ b/src/kiwano/renderer/RenderTarget.cpp @@ -397,6 +397,29 @@ namespace kiwano ThrowIfFailed(hr); } + void RenderTarget::CreateTexture(Texture& texture, math::Vec2T size, D2D1_PIXEL_FORMAT format) + { + HRESULT hr = S_OK; + + if (!render_target_) + { + hr = E_UNEXPECTED; + } + + if (SUCCEEDED(hr)) + { + ComPtr saved_bitmap; + hr = render_target_->CreateBitmap(D2D1::SizeU(size.x, size.y), D2D1::BitmapProperties(format), &saved_bitmap); + + if (SUCCEEDED(hr)) + { + texture.SetBitmap(saved_bitmap); + } + } + + ThrowIfFailed(hr); + } + void RenderTarget::CreateLayer(LayerArea& layer) { HRESULT hr = S_OK; @@ -714,26 +737,22 @@ namespace kiwano { } - TexturePtr TextureRenderTarget::GetOutput() + TexturePtr TextureRenderTarget::GetOutput() const { HRESULT hr = E_FAIL; TexturePtr output; - if (GetRenderTarget()) + if (bitmap_rt_) { - ComPtr bitmap_rt; - hr = GetRenderTarget()->QueryInterface(&bitmap_rt); + ComPtr bitmap_rt = bitmap_rt_; + ComPtr bitmap; + + hr = bitmap_rt->GetBitmap(&bitmap); if (SUCCEEDED(hr)) { - ComPtr bitmap; - hr = bitmap_rt->GetBitmap(&bitmap); - - if (SUCCEEDED(hr)) - { - output = new Texture; - output->SetBitmap(bitmap); - } + output = new Texture; + output->SetBitmap(bitmap); } } diff --git a/src/kiwano/renderer/RenderTarget.h b/src/kiwano/renderer/RenderTarget.h index 3d584fb0..241d35e7 100644 --- a/src/kiwano/renderer/RenderTarget.h +++ b/src/kiwano/renderer/RenderTarget.h @@ -20,6 +20,7 @@ #pragma once #include +#include #include #include #include @@ -30,6 +31,11 @@ namespace kiwano { + class Renderer; + + KGE_DECLARE_SMART_PTR(RenderTarget); + KGE_DECLARE_SMART_PTR(TextureRenderTarget); + // 文字抗锯齿模式 enum class TextAntialiasMode { @@ -42,7 +48,7 @@ namespace kiwano // 渲染目标 class KGE_API RenderTarget - : public Noncopyable + : public ObjectBase { public: bool IsValid() const; @@ -51,10 +57,6 @@ namespace kiwano void EndDraw(); - void CreateLayer( - LayerArea& layer - ); - void DrawGeometry( Geometry const& geometry, float stroke_width, @@ -123,6 +125,16 @@ namespace kiwano Point const& offset = Point{} ); + void CreateTexture( + Texture& texture, + math::Vec2T size, + D2D1_PIXEL_FORMAT format + ); + + void CreateLayer( + LayerArea& layer + ); + void PushClipRect( Rect const& clip_rect ); @@ -203,19 +215,17 @@ namespace kiwano inline Status const& GetStatus() const { return status_; } + protected: inline ComPtr GetRenderTarget() const { KGE_ASSERT(render_target_); return render_target_; } inline ComPtr GetTextRenderer() const { KGE_ASSERT(text_renderer_); return text_renderer_; } ComPtr GetStrokeStyle(StrokeStyle style); - public: + protected: RenderTarget(); - HRESULT CreateDeviceResources( - ComPtr rt, - ComPtr dev_res - ); + HRESULT CreateDeviceResources(ComPtr rt, ComPtr dev_res); void DiscardDeviceResources(); @@ -239,9 +249,36 @@ namespace kiwano class KGE_API TextureRenderTarget : public RenderTarget { + friend class Renderer; + public: + bool IsValid() const; + + TexturePtr GetOutput() const; + + private: TextureRenderTarget(); - TexturePtr GetOutput(); + ComPtr GetBitmapRenderTarget() const; + + void SetBitmapRenderTarget(ComPtr rt); + + private: + ComPtr bitmap_rt_; }; + + inline bool TextureRenderTarget::IsValid() const + { + return !!bitmap_rt_; + } + + inline ComPtr TextureRenderTarget::GetBitmapRenderTarget() const + { + return bitmap_rt_; + } + + inline void TextureRenderTarget::SetBitmapRenderTarget(ComPtr rt) + { + bitmap_rt_ = rt; + } } diff --git a/src/kiwano/renderer/Renderer.cpp b/src/kiwano/renderer/Renderer.cpp index f04f2d26..00bcbd05 100644 --- a/src/kiwano/renderer/Renderer.cpp +++ b/src/kiwano/renderer/Renderer.cpp @@ -835,7 +835,7 @@ namespace kiwano ThrowIfFailed(hr); } - void Renderer::CreatePathGeometrySink(GeometrySink& sink) + void Renderer::CreateGeometrySink(GeometrySink& sink) { HRESULT hr = S_OK; if (!d2d_res_) @@ -857,7 +857,7 @@ namespace kiwano ThrowIfFailed(hr); } - void Renderer::CreateTextureRenderTarget(TextureRenderTarget& render_target) + void Renderer::CreateTextureRenderTarget(TextureRenderTargetPtr& render_target) { HRESULT hr = S_OK; if (!d2d_res_) @@ -865,15 +865,27 @@ namespace kiwano hr = E_UNEXPECTED; } - ComPtr output; + TextureRenderTargetPtr output; if (SUCCEEDED(hr)) { - hr = d2d_res_->GetDeviceContext()->CreateCompatibleRenderTarget(&output); + ComPtr bitmap_rt; + hr = d2d_res_->GetDeviceContext()->CreateCompatibleRenderTarget(&bitmap_rt); + + if (SUCCEEDED(hr)) + { + output = new TextureRenderTarget; + hr = output->CreateDeviceResources(bitmap_rt, d2d_res_); + } + + if (SUCCEEDED(hr)) + { + output->SetBitmapRenderTarget(bitmap_rt); + } } if (SUCCEEDED(hr)) { - hr = render_target.CreateDeviceResources(output, d2d_res_); + render_target = output; } ThrowIfFailed(hr); diff --git a/src/kiwano/renderer/Renderer.h b/src/kiwano/renderer/Renderer.h index 23eb32d0..d73155d2 100644 --- a/src/kiwano/renderer/Renderer.h +++ b/src/kiwano/renderer/Renderer.h @@ -141,12 +141,12 @@ namespace kiwano Vec2 const& radius ); - void CreatePathGeometrySink( + void CreateGeometrySink( GeometrySink& sink ); void CreateTextureRenderTarget( - TextureRenderTarget& render_target + TextureRenderTargetPtr& render_target ); void CreateSolidBrush( diff --git a/src/kiwano/renderer/TextLayout.h b/src/kiwano/renderer/TextLayout.h index d6424eaa..00c70e54 100644 --- a/src/kiwano/renderer/TextLayout.h +++ b/src/kiwano/renderer/TextLayout.h @@ -24,10 +24,16 @@ namespace kiwano { + class RenderTarget; + class Renderer; + /// \~chinese /// @brief 文本布局 class KGE_API TextLayout { + friend class RenderTarget; + friend class Renderer; + public: /// \~chinese /// @brief 构造空的文本布局 @@ -136,7 +142,7 @@ namespace kiwano /// @param length 长度 void SetStrikethrough(bool enable, uint32_t start, uint32_t length); - public: + private: ComPtr GetTextFormat() const; void SetTextFormat(ComPtr format); diff --git a/src/kiwano/renderer/Texture.cpp b/src/kiwano/renderer/Texture.cpp index 83494a05..e0727631 100644 --- a/src/kiwano/renderer/Texture.cpp +++ b/src/kiwano/renderer/Texture.cpp @@ -31,24 +31,6 @@ namespace kiwano { } - Texture::Texture(String const& file_path) - : Texture() - { - Load(file_path); - } - - Texture::Texture(Resource const& res) - : Texture() - { - Load(res); - } - - Texture::Texture(ComPtr const & bitmap) - : Texture() - { - SetBitmap(bitmap); - } - Texture::~Texture() { } diff --git a/src/kiwano/renderer/Texture.h b/src/kiwano/renderer/Texture.h index ca83097d..c2c85ea7 100644 --- a/src/kiwano/renderer/Texture.h +++ b/src/kiwano/renderer/Texture.h @@ -24,6 +24,10 @@ namespace kiwano { + class RenderTarget; + class TextureRenderTarget; + class Renderer; + // 插值模式 // 插值模式指定了位图在缩放和旋转时像素颜色的计算方式 // Linear (双线性插值): 对周围四个像素进行两次线性插值计算, 在图像放大时可能会模糊(默认) @@ -40,21 +44,13 @@ namespace kiwano class KGE_API Texture : public ObjectBase { + friend class RenderTarget; + friend class TextureRenderTarget; + friend class Renderer; + public: Texture(); - explicit Texture( - String const& file_path - ); - - explicit Texture( - Resource const& res - ); - - explicit Texture( - ComPtr const& bitmap - ); - virtual ~Texture(); // 加载本地文件 @@ -91,6 +87,9 @@ namespace kiwano // 获取像素插值方式 InterpolationMode GetBitmapInterpolationMode() const; + // 获取像素格式 + D2D1_PIXEL_FORMAT GetPixelFormat() const; + // 拷贝位图内存 void CopyFrom(TexturePtr copy_from); @@ -103,16 +102,13 @@ namespace kiwano // 设置默认的像素插值方式 static void SetDefaultInterpolationMode(InterpolationMode mode); - public: + private: // 获取源位图 ComPtr GetBitmap() const; // 设置源位图 void SetBitmap(ComPtr bitmap); - // 获取像素格式 - D2D1_PIXEL_FORMAT GetPixelFormat() const; - private: ComPtr bitmap_; InterpolationMode interpolation_mode_;