From dc5ec25c001790b731285f8419965afe9987ce33 Mon Sep 17 00:00:00 2001 From: Nomango Date: Tue, 19 Sep 2023 20:25:06 +0800 Subject: [PATCH] feat: update to direct2d 1.3 --- projects/kiwano/kiwano.vcxproj | 1 - projects/kiwano/kiwano.vcxproj.filters | 15 +- src/kiwano/2d/Canvas.cpp | 26 +-- src/kiwano/2d/Canvas.h | 17 +- src/kiwano/2d/GifSprite.cpp | 4 +- src/kiwano/2d/TextActor.cpp | 3 +- src/kiwano/CMakeLists.txt | 5 +- src/kiwano/render/Brush.cpp | 6 +- src/kiwano/render/Brush.h | 2 +- .../render/DirectX/D2DDeviceResources.cpp | 16 +- .../render/DirectX/D2DDeviceResources.h | 9 - .../render/DirectX/FontCollectionLoader.cpp | 17 +- .../render/DirectX/FontCollectionLoader.h | 6 + src/kiwano/render/DirectX/NativePtr.h | 79 ------- .../render/DirectX/RenderContextImpl.cpp | 216 ++++++++++-------- src/kiwano/render/DirectX/RenderContextImpl.h | 17 +- src/kiwano/render/DirectX/RendererImpl.cpp | 148 ++++++------ src/kiwano/render/DirectX/RendererImpl.h | 4 +- .../render/DirectX/TextDrawingEffect.cpp | 10 +- src/kiwano/render/DirectX/TextDrawingEffect.h | 10 +- src/kiwano/render/DirectX/TextRenderer.cpp | 63 ++--- src/kiwano/render/DirectX/TextRenderer.h | 13 +- src/kiwano/render/DirectX/helper.h | 25 +- src/kiwano/render/Font.h | 2 +- src/kiwano/render/GifImage.cpp | 3 +- src/kiwano/render/NativeObject.cpp | 5 +- src/kiwano/render/NativeObject.h | 48 +++- src/kiwano/render/RenderContext.cpp | 9 +- src/kiwano/render/RenderContext.h | 23 +- src/kiwano/render/Renderer.h | 2 +- src/kiwano/render/Shape.cpp | 16 +- src/kiwano/render/ShapeMaker.cpp | 30 ++- src/kiwano/render/TextLayout.cpp | 20 +- src/kiwano/render/Texture.cpp | 12 +- src/kiwano/render/Texture.h | 1 - 35 files changed, 427 insertions(+), 456 deletions(-) delete mode 100644 src/kiwano/render/DirectX/NativePtr.h diff --git a/projects/kiwano/kiwano.vcxproj b/projects/kiwano/kiwano.vcxproj index a3910d00..7e76543c 100644 --- a/projects/kiwano/kiwano.vcxproj +++ b/projects/kiwano/kiwano.vcxproj @@ -96,7 +96,6 @@ - diff --git a/projects/kiwano/kiwano.vcxproj.filters b/projects/kiwano/kiwano.vcxproj.filters index 8853f034..399185c7 100644 --- a/projects/kiwano/kiwano.vcxproj.filters +++ b/projects/kiwano/kiwano.vcxproj.filters @@ -222,12 +222,6 @@ core - - render - - - render\DirectX - render @@ -411,6 +405,9 @@ render\DirectX + + render + @@ -608,9 +605,6 @@ render - - render - core @@ -677,6 +671,9 @@ render\DirectX + + render + diff --git a/src/kiwano/2d/Canvas.cpp b/src/kiwano/2d/Canvas.cpp index d857ce3a..28bcc535 100644 --- a/src/kiwano/2d/Canvas.cpp +++ b/src/kiwano/2d/Canvas.cpp @@ -25,10 +25,9 @@ namespace kiwano { Canvas::Canvas() { - RecreateContext(nullptr); } -Canvas::Canvas(const Size& size) +Canvas::Canvas(const PixelSize& size) { ResizeAndClear(size); } @@ -39,24 +38,10 @@ CanvasRenderContextPtr Canvas::GetContext2D() const return ctx; } -void Canvas::ResizeAndClear(Size size) -{ - RecreateContext(&size); -} - -void Canvas::RecreateContext(Size* size) +void Canvas::ResizeAndClear(const PixelSize& size) { texture_cached_ = MakePtr(); - - if (size) - { - render_ctx_ = RenderContext::Create(*texture_cached_, *size); - } - else - { - render_ctx_ = RenderContext::Create(*texture_cached_); - } - + render_ctx_ = RenderContext::Create(texture_cached_, size); if (render_ctx_) { SetSize(render_ctx_->GetSize()); @@ -67,11 +52,6 @@ void Canvas::RecreateContext(Size* size) } } -TexturePtr Canvas::ExportToTexture() const -{ - return texture_cached_; -} - void Canvas::OnRender(RenderContext& ctx) { if (texture_cached_) diff --git a/src/kiwano/2d/Canvas.h b/src/kiwano/2d/Canvas.h index 0cfccb59..cee5df73 100644 --- a/src/kiwano/2d/Canvas.h +++ b/src/kiwano/2d/Canvas.h @@ -43,12 +43,15 @@ KGE_DECLARE_SMART_PTR(CanvasRenderContext); class KGE_API Canvas : public Actor { public: + /// \~chinese + /// @brief 创建画布 + /// @warning 必须调用 ResizeAndClear 以初始化画布 Canvas(); /// \~chinese /// @brief 创建画布 /// @param size 画布大小 - Canvas(const Size& size); + Canvas(const PixelSize& size); /// \~chinese /// @brief 获取2D绘图上下文 @@ -57,17 +60,14 @@ public: /// \~chinese /// @brief 清空画布大小并重设画布大小 /// @warning 该函数会导致原绘图上下文失效 - void ResizeAndClear(Size size); + void ResizeAndClear(const PixelSize& size); /// \~chinese /// @brief 导出纹理 - TexturePtr ExportToTexture() const; + TexturePtr GetTexture() const; void OnRender(RenderContext& ctx) override; -private: - void RecreateContext(Size* size); - private: TexturePtr texture_cached_; RenderContextPtr render_ctx_; @@ -285,6 +285,11 @@ private: /** @} */ +inline TexturePtr Canvas::GetTexture() const +{ + return texture_cached_; +} + inline void CanvasRenderContext::BeginDraw() { KGE_ASSERT(ctx_); diff --git a/src/kiwano/2d/GifSprite.cpp b/src/kiwano/2d/GifSprite.cpp index ee18cf5a..dcb8fa52 100644 --- a/src/kiwano/2d/GifSprite.cpp +++ b/src/kiwano/2d/GifSprite.cpp @@ -20,6 +20,7 @@ #include #include +#include namespace kiwano { @@ -76,9 +77,8 @@ bool GifSprite::Load(GifImagePtr gif) frame_to_render_.Reset(); frame_rt_.Reset(); - Size frame_size = Size(float(gif_->GetWidthInPixels()), float(gif_->GetHeightInPixels())); frame_to_render_ = MakePtr(); - frame_rt_ = RenderContext::Create(*frame_to_render_, frame_size); + frame_rt_ = RenderContext::Create(frame_to_render_, gif_->GetSizeInPixels()); if (frame_rt_) { diff --git a/src/kiwano/2d/TextActor.cpp b/src/kiwano/2d/TextActor.cpp index 25c732ed..d6ad7056 100644 --- a/src/kiwano/2d/TextActor.cpp +++ b/src/kiwano/2d/TextActor.cpp @@ -289,7 +289,8 @@ void TextActor::UpdateCachedTexture() const auto expectedSize = layout_->GetSize() + cached_texture_offset * 2; if (!render_ctx_) { - render_ctx_ = RenderContext::Create(*texture_cached_, expectedSize); + const auto pixelSize = PixelSize((uint32_t)math::Ceil(expectedSize.x), (uint32_t)math::Ceil(expectedSize.y)); + render_ctx_ = RenderContext::Create(texture_cached_, pixelSize); } else if (render_ctx_->GetSize() != expectedSize) { diff --git a/src/kiwano/CMakeLists.txt b/src/kiwano/CMakeLists.txt index cbb8d953..7b94a9fa 100644 --- a/src/kiwano/CMakeLists.txt +++ b/src/kiwano/CMakeLists.txt @@ -100,6 +100,8 @@ set(SOURCE_FILES math/Transform.hpp math/Vec2.hpp platform/win32/ComPtr.hpp + platform/win32/ComObject.cpp + platform/win32/ComObject.h platform/win32/libraries.cpp platform/win32/libraries.h platform/win32/WindowImpl.cpp @@ -113,6 +115,8 @@ set(SOURCE_FILES platform/Runner.h platform/Window.cpp platform/Window.h + platform/NativeObject.cpp + platform/NativeObject.h render/DirectX/D2DDeviceResources.cpp render/DirectX/D2DDeviceResources.h render/DirectX/D3D10DeviceResources.cpp @@ -123,7 +127,6 @@ set(SOURCE_FILES render/DirectX/FontCollectionLoader.cpp render/DirectX/FontCollectionLoader.h render/DirectX/helper.h - render/DirectX/NativePtr.h render/DirectX/RenderContextImpl.cpp render/DirectX/RenderContextImpl.h render/DirectX/RendererImpl.cpp diff --git a/src/kiwano/render/Brush.cpp b/src/kiwano/render/Brush.cpp index 9b09d60c..ab25d187 100644 --- a/src/kiwano/render/Brush.cpp +++ b/src/kiwano/render/Brush.cpp @@ -22,10 +22,6 @@ #include #include -#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX -#include -#endif - namespace kiwano { GradientStop::GradientStop() @@ -124,7 +120,7 @@ void Brush::SetTransform(const Transform& transform) void Brush::SetTransform(const Matrix3x2& transform) { #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); KGE_ASSERT(native); if (native) diff --git a/src/kiwano/render/Brush.h b/src/kiwano/render/Brush.h index c4545b2a..e54da60f 100644 --- a/src/kiwano/render/Brush.h +++ b/src/kiwano/render/Brush.h @@ -19,8 +19,8 @@ // THE SOFTWARE. #pragma once -#include #include +#include #include namespace kiwano diff --git a/src/kiwano/render/DirectX/D2DDeviceResources.cpp b/src/kiwano/render/DirectX/D2DDeviceResources.cpp index 6cd2e507..5b45256e 100644 --- a/src/kiwano/render/DirectX/D2DDeviceResources.cpp +++ b/src/kiwano/render/DirectX/D2DDeviceResources.cpp @@ -92,8 +92,6 @@ public: void DiscardResources() override; - void SetTargetBitmap(_In_ ComPtr target) override; - void ResetTextRenderingParams(_In_ HMONITOR monitor) override; public: @@ -213,7 +211,6 @@ void D2DDeviceResources::DiscardResources() } } - target_bitmap_.Reset(); device_context_.Reset(); device_.Reset(); @@ -315,7 +312,7 @@ HRESULT D2DDeviceResources::CreateDeviceResources(_In_ ComPtr dxgi_ { ComPtr device_ctx; - hr = device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &device_ctx); + hr = device->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, &device_ctx); if (SUCCEEDED(hr)) { @@ -350,7 +347,7 @@ HRESULT D2DDeviceResources::CreateWindowSizeDependentResources() if (SUCCEEDED(hr)) { - SetTargetBitmap(target); + device_context_->SetTarget(target.Get()); } } return hr; @@ -384,15 +381,6 @@ HRESULT D2DDeviceResources::HandleDeviceLost(_In_ ComPtr dxgi_devic return hr; } -void D2DDeviceResources::SetTargetBitmap(ComPtr target) -{ - target_bitmap_ = target; - if (device_context_) - { - device_context_->SetTarget(target_bitmap_.Get()); - } -} - void D2DDeviceResources::ResetTextRenderingParams(HMONITOR monitor) { if (!dwrite_factory_ || device_context_) diff --git a/src/kiwano/render/DirectX/D2DDeviceResources.h b/src/kiwano/render/DirectX/D2DDeviceResources.h index 7c00daec..d59cb1cd 100644 --- a/src/kiwano/render/DirectX/D2DDeviceResources.h +++ b/src/kiwano/render/DirectX/D2DDeviceResources.h @@ -78,8 +78,6 @@ public: virtual void DiscardResources() = 0; - virtual void SetTargetBitmap(_In_ ComPtr target) = 0; - virtual void ResetTextRenderingParams(_In_ HMONITOR monitor) = 0; inline ID2D1Factory1* GetFactory() @@ -112,17 +110,10 @@ public: return device_context_.Get(); } - inline ID2D1Bitmap1* GetTargetBitmap() - { - KGE_ASSERT(target_bitmap_); - return target_bitmap_.Get(); - } - protected: ComPtr factory_; ComPtr device_; ComPtr device_context_; - ComPtr target_bitmap_; ComPtr imaging_factory_; ComPtr dwrite_factory_; diff --git a/src/kiwano/render/DirectX/FontCollectionLoader.cpp b/src/kiwano/render/DirectX/FontCollectionLoader.cpp index 826b35d2..8b9deba2 100644 --- a/src/kiwano/render/DirectX/FontCollectionLoader.cpp +++ b/src/kiwano/render/DirectX/FontCollectionLoader.cpp @@ -22,6 +22,10 @@ namespace kiwano { +namespace graphics +{ +namespace directx +{ //////////////////////////////////////////////////////////////////////////////////////// // // FontCollectionLoader @@ -41,7 +45,7 @@ public: // IDWriteFontCollectionLoader methods virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(IDWriteFactory* pFactory, void const* collectionKey, - uint32_t collectionKeySize, + uint32_t collectionKeySize, _Out_ IDWriteFontFileEnumerator** fontFileEnumerator); // IUnknown methods @@ -348,7 +352,7 @@ public: // IDWriteFontCollectionLoader methods virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(IDWriteFactory* pFactory, void const* collectionKey, - uint32_t collectionKeySize, + uint32_t collectionKeySize, _Out_ IDWriteFontFileEnumerator** fontFileEnumerator); // IUnknown methods @@ -389,8 +393,7 @@ HRESULT IResourceFontCollectionLoader::Create(_Out_ IResourceFontCollectionLoade return hr; } -STDMETHODIMP ResourceFontCollectionLoader::AddResources(const Vector& data, - _Out_ LPVOID* pCollectionKey, +STDMETHODIMP ResourceFontCollectionLoader::AddResources(const Vector& data, _Out_ LPVOID* pCollectionKey, _Out_ uint32_t* pCollectionKeySize) { if (!pCollectionKey || !pCollectionKeySize) @@ -492,8 +495,8 @@ public: } // IDWriteFontFileLoader methods - virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey, - uint32_t fontFileReferenceKeySize, + virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey, + uint32_t fontFileReferenceKeySize, _Out_ IDWriteFontFileStream** fontFileStream); // IUnknown methods @@ -891,4 +894,6 @@ ULONG STDMETHODCALLTYPE ResourceFontFileStream::Release() return newCount; } +} // namespace directx +} // namespace graphics } // namespace kiwano diff --git a/src/kiwano/render/DirectX/FontCollectionLoader.h b/src/kiwano/render/DirectX/FontCollectionLoader.h index bd23c445..a7d7816f 100644 --- a/src/kiwano/render/DirectX/FontCollectionLoader.h +++ b/src/kiwano/render/DirectX/FontCollectionLoader.h @@ -25,6 +25,10 @@ namespace kiwano { +namespace graphics +{ +namespace directx +{ interface DWRITE_DECLARE_INTERFACE("7EC7A55A-1964-4098-83E0-EFA7C12C6EF7") IFontCollectionLoader : public IDWriteFontCollectionLoader { @@ -78,4 +82,6 @@ public: static HRESULT Create(_Out_ IResourceFontFileStream** ppStream, const BinaryData& data); }; +} // namespace directx +} // namespace graphics } // namespace kiwano diff --git a/src/kiwano/render/DirectX/NativePtr.h b/src/kiwano/render/DirectX/NativePtr.h deleted file mode 100644 index 2e132d68..00000000 --- a/src/kiwano/render/DirectX/NativePtr.h +++ /dev/null @@ -1,79 +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. - -#pragma once -#include -#include -#include - -namespace kiwano -{ - -class KGE_API NativePtr -{ -public: - template ::value, int>::type> - static inline ComPtr<_Ty> Get(const NativeObject* object) - { - if (object) - { - ComPtr ptr = object->GetNativePointer(); - if (ptr) - { - ComPtr<_Ty> native; - if (SUCCEEDED(ptr->QueryInterface<_Ty>(&native))) - return native; - } - } - return nullptr; - } - - template - static inline ComPtr<_Ty> Get(const NativeObject& object) - { - return NativePtr::Get<_Ty>(&object); - } - - template - static inline ComPtr<_Ty> Get(NativeObjectPtr object) - { - return NativePtr::Get<_Ty>(object.Get()); - } - - static inline void Set(NativeObject* object, ComPtr com_ptr) - { - if (object) - { - object->ResetNativePointer(com_ptr.Get()); - } - } - - static inline void Set(NativeObject& object, ComPtr com_ptr) - { - NativePtr::Set(&object, com_ptr); - } - - static inline void Set(NativeObjectPtr object, ComPtr com_ptr) - { - NativePtr::Set(object.Get(), com_ptr); - } -}; - -} // namespace kiwano diff --git a/src/kiwano/render/DirectX/RenderContextImpl.cpp b/src/kiwano/render/DirectX/RenderContextImpl.cpp index d22990b0..28d91082 100644 --- a/src/kiwano/render/DirectX/RenderContextImpl.cpp +++ b/src/kiwano/render/DirectX/RenderContextImpl.cpp @@ -19,13 +19,15 @@ // THE SOFTWARE. #include -#include #include #include namespace kiwano { - +namespace graphics +{ +namespace directx +{ RenderContextImpl::RenderContextImpl() {} RenderContextImpl::~RenderContextImpl() @@ -33,23 +35,23 @@ RenderContextImpl::~RenderContextImpl() DiscardDeviceResources(); } -HRESULT RenderContextImpl::CreateDeviceResources(ComPtr factory, ComPtr render_target) +HRESULT RenderContextImpl::CreateDeviceResources(ComPtr factory, ComPtr ctx) { - if (!factory || !render_target) + if (!factory || !ctx) return E_INVALIDARG; - render_target_ = render_target; + render_ctx_ = ctx; text_renderer_.Reset(); current_brush_.Reset(); - HRESULT hr = ITextRenderer::Create(&text_renderer_, render_target_.Get()); + HRESULT hr = ITextRenderer::Create(&text_renderer_, render_ctx_.Get()); if (SUCCEEDED(hr)) { SetAntialiasMode(antialias_); SetTextAntialiasMode(text_antialias_); - Resize(reinterpret_cast(render_target->GetSize())); + Resize(reinterpret_cast(render_ctx_->GetSize())); } // DrawingStateBlock @@ -60,7 +62,7 @@ HRESULT RenderContextImpl::CreateDeviceResources(ComPtr factory, C if (SUCCEEDED(hr)) { - NativePtr::Set(this, render_target); + NativeObject::Set(this, ctx); } return hr; } @@ -68,28 +70,42 @@ HRESULT RenderContextImpl::CreateDeviceResources(ComPtr factory, C void RenderContextImpl::DiscardDeviceResources() { text_renderer_.Reset(); - render_target_.Reset(); + render_ctx_.Reset(); current_brush_.Reset(); ResetNativePointer(); } +TexturePtr RenderContextImpl::GetTarget() const +{ + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); + + ComPtr target; + render_ctx_->GetTarget(&target); + if (target) + { + TexturePtr ptr = MakePtr(); + NativeObject::Set(*ptr, target.Get()); + } + return nullptr; +} + void RenderContextImpl::BeginDraw() { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); SaveDrawingState(); RenderContext::BeginDraw(); - render_target_->BeginDraw(); + render_ctx_->BeginDraw(); } void RenderContextImpl::EndDraw() { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); - HRESULT hr = render_target_->EndDraw(); + HRESULT hr = render_ctx_->EndDraw(); KGE_THROW_IF_FAILED(hr, "ID2D1RenderTarget EndDraw failed"); RenderContext::EndDraw(); @@ -97,9 +113,25 @@ void RenderContextImpl::EndDraw() RestoreDrawingState(); } +void RenderContextImpl::CreateTexture(Texture& texture, const PixelSize& size) +{ + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); + + ComPtr saved_bitmap; + + HRESULT hr = render_ctx_->CreateBitmap(D2D1::SizeU(size.x, size.y), D2D1::BitmapProperties(), &saved_bitmap); + + if (SUCCEEDED(hr)) + { + NativeObject::Set(texture, saved_bitmap); + } + + KGE_THROW_IF_FAILED(hr, "Create texture failed"); +} + void RenderContextImpl::DrawTexture(const Texture& texture, const Rect* src_rect, const Rect* dest_rect) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); if (texture.IsValid()) { @@ -113,8 +145,8 @@ void RenderContextImpl::DrawTexture(const Texture& texture, const Rect* src_rect mode = D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR; } - auto bitmap = NativePtr::Get(texture); - render_target_->DrawBitmap(bitmap.Get(), dest_rect ? &DX::ConvertToRectF(*dest_rect) : nullptr, brush_opacity_, + auto bitmap = NativeObject::Get(texture); + render_ctx_->DrawBitmap(bitmap.Get(), dest_rect ? &DX::ConvertToRectF(*dest_rect) : nullptr, brush_opacity_, mode, src_rect ? &DX::ConvertToRectF(*src_rect) : nullptr); IncreasePrimitivesCount(); @@ -127,10 +159,10 @@ void RenderContextImpl::DrawTextLayout(const TextLayout& layout, const Point& of if (layout.IsValid()) { - auto native = NativePtr::Get(layout); - auto fill_brush = NativePtr::Get(current_brush_); - auto outline_brush = NativePtr::Get(current_outline_brush); - auto outline_stroke = NativePtr::Get(current_stroke_); + auto native = NativeObject::Get(layout); + auto fill_brush = NativeObject::Get(current_brush_); + auto outline_brush = NativeObject::Get(current_outline_brush); + auto outline_stroke = NativeObject::Get(current_stroke_); float outline_width = 1.0f; if (fill_brush) @@ -164,17 +196,17 @@ void RenderContextImpl::DrawTextLayout(const TextLayout& layout, const Point& of void RenderContextImpl::DrawShape(const Shape& shape) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!"); if (shape.IsValid()) { - auto geometry = NativePtr::Get(shape); - auto brush = NativePtr::Get(current_brush_); - auto stroke_style = NativePtr::Get(current_stroke_); + auto geometry = NativeObject::Get(shape); + auto brush = NativeObject::Get(current_brush_); + auto stroke_style = NativeObject::Get(current_stroke_); float stroke_width = current_stroke_ ? current_stroke_->GetWidth() : 1.0f; - render_target_->DrawGeometry(geometry.Get(), brush.Get(), stroke_width, stroke_style.Get()); + render_ctx_->DrawGeometry(geometry.Get(), brush.Get(), stroke_width, stroke_style.Get()); IncreasePrimitivesCount(); } @@ -182,14 +214,14 @@ void RenderContextImpl::DrawShape(const Shape& shape) void RenderContextImpl::DrawLine(const Point& point1, const Point& point2) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!"); - auto brush = NativePtr::Get(current_brush_); - auto stroke_style = NativePtr::Get(current_stroke_); + auto brush = NativeObject::Get(current_brush_); + auto stroke_style = NativeObject::Get(current_stroke_); float stroke_width = current_stroke_ ? current_stroke_->GetWidth() : 1.0f; - render_target_->DrawLine(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2), brush.Get(), stroke_width, + render_ctx_->DrawLine(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2), brush.Get(), stroke_width, stroke_style.Get()); IncreasePrimitivesCount(); @@ -197,28 +229,28 @@ void RenderContextImpl::DrawLine(const Point& point1, const Point& point2) void RenderContextImpl::DrawRectangle(const Rect& rect) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!"); - auto brush = NativePtr::Get(current_brush_); - auto stroke_style = NativePtr::Get(current_stroke_); + auto brush = NativeObject::Get(current_brush_); + auto stroke_style = NativeObject::Get(current_stroke_); float stroke_width = current_stroke_ ? current_stroke_->GetWidth() : 1.0f; - render_target_->DrawRectangle(DX::ConvertToRectF(rect), brush.Get(), stroke_width, stroke_style.Get()); + render_ctx_->DrawRectangle(DX::ConvertToRectF(rect), brush.Get(), stroke_width, stroke_style.Get()); IncreasePrimitivesCount(); } void RenderContextImpl::DrawRoundedRectangle(const Rect& rect, const Vec2& radius) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!"); - auto brush = NativePtr::Get(current_brush_); - auto stroke_style = NativePtr::Get(current_stroke_); + auto brush = NativeObject::Get(current_brush_); + auto stroke_style = NativeObject::Get(current_stroke_); float stroke_width = current_stroke_ ? current_stroke_->GetWidth() : 1.0f; - render_target_->DrawRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y), brush.Get(), + render_ctx_->DrawRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y), brush.Get(), stroke_width, stroke_style.Get()); IncreasePrimitivesCount(); @@ -226,14 +258,14 @@ void RenderContextImpl::DrawRoundedRectangle(const Rect& rect, const Vec2& radiu void RenderContextImpl::DrawEllipse(const Point& center, const Vec2& radius) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!"); - auto brush = NativePtr::Get(current_brush_); - auto stroke_style = NativePtr::Get(current_stroke_); + auto brush = NativeObject::Get(current_brush_); + auto stroke_style = NativeObject::Get(current_stroke_); float stroke_width = current_stroke_ ? current_stroke_->GetWidth() : 1.0f; - render_target_->DrawEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y), brush.Get(), + render_ctx_->DrawEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y), brush.Get(), stroke_width, stroke_style.Get()); IncreasePrimitivesCount(); @@ -241,14 +273,14 @@ void RenderContextImpl::DrawEllipse(const Point& center, const Vec2& radius) void RenderContextImpl::FillShape(const Shape& shape) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!"); if (shape.IsValid()) { - auto brush = NativePtr::Get(current_brush_); - auto geometry = NativePtr::Get(shape); - render_target_->FillGeometry(geometry.Get(), brush.Get()); + auto brush = NativeObject::Get(current_brush_); + auto geometry = NativeObject::Get(shape); + render_ctx_->FillGeometry(geometry.Get(), brush.Get()); IncreasePrimitivesCount(); } @@ -256,56 +288,40 @@ void RenderContextImpl::FillShape(const Shape& shape) void RenderContextImpl::FillRectangle(const Rect& rect) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!"); - auto brush = NativePtr::Get(current_brush_); - render_target_->FillRectangle(DX::ConvertToRectF(rect), brush.Get()); + auto brush = NativeObject::Get(current_brush_); + render_ctx_->FillRectangle(DX::ConvertToRectF(rect), brush.Get()); IncreasePrimitivesCount(); } void RenderContextImpl::FillRoundedRectangle(const Rect& rect, const Vec2& radius) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!"); - auto brush = NativePtr::Get(current_brush_); - render_target_->FillRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y), brush.Get()); + auto brush = NativeObject::Get(current_brush_); + render_ctx_->FillRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y), brush.Get()); IncreasePrimitivesCount(); } void RenderContextImpl::FillEllipse(const Point& center, const Vec2& radius) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!"); - auto brush = NativePtr::Get(current_brush_); - render_target_->FillEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y), brush.Get()); + auto brush = NativeObject::Get(current_brush_); + render_ctx_->FillEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y), brush.Get()); IncreasePrimitivesCount(); } -void RenderContextImpl::CreateTexture(Texture& texture, math::Vec2T size) -{ - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); - - ComPtr saved_bitmap; - - HRESULT hr = render_target_->CreateBitmap(D2D1::SizeU(size.x, size.y), D2D1::BitmapProperties(), &saved_bitmap); - - if (SUCCEEDED(hr)) - { - NativePtr::Set(texture, saved_bitmap); - } - - KGE_THROW_IF_FAILED(hr, "Create texture failed"); -} - void RenderContextImpl::PushClipRect(const Rect& clip_rect) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); D2D1_ANTIALIAS_MODE mode; if (antialias_) @@ -316,29 +332,29 @@ void RenderContextImpl::PushClipRect(const Rect& clip_rect) { mode = D2D1_ANTIALIAS_MODE_ALIASED; } - render_target_->PushAxisAlignedClip(DX::ConvertToRectF(clip_rect), mode); + render_ctx_->PushAxisAlignedClip(DX::ConvertToRectF(clip_rect), mode); } void RenderContextImpl::PopClipRect() { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); - render_target_->PopAxisAlignedClip(); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); + render_ctx_->PopAxisAlignedClip(); } void RenderContextImpl::PushLayer(Layer& layer) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); - auto native = NativePtr::Get(layer); - auto mask = NativePtr::Get(layer.GetMaskShape()); + auto native = NativeObject::Get(layer); + auto mask = NativeObject::Get(layer.GetMaskShape()); if (!native) { - HRESULT hr = render_target_->CreateLayer(&native); + HRESULT hr = render_ctx_->CreateLayer(&native); if (SUCCEEDED(hr)) { - NativePtr::Set(layer, native); + NativeObject::Set(layer, native); } KGE_THROW_IF_FAILED(hr, "Create ID2D1Layer failed"); } @@ -348,32 +364,32 @@ void RenderContextImpl::PushLayer(Layer& layer) DX::ConvertToMatrix3x2F(layer.GetMaskTransform()), layer.GetOpacity(), nullptr, D2D1_LAYER_OPTIONS_NONE); - render_target_->PushLayer(params, native.Get()); + render_ctx_->PushLayer(params, native.Get()); } void RenderContextImpl::PopLayer() { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); - render_target_->PopLayer(); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); + render_ctx_->PopLayer(); } void RenderContextImpl::Clear() { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); - render_target_->Clear(); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); + render_ctx_->Clear(); } void RenderContextImpl::Clear(const Color& clear_color) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); - render_target_->Clear(DX::ConvertToColorF(clear_color)); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); + render_ctx_->Clear(DX::ConvertToColorF(clear_color)); } Size RenderContextImpl::GetSize() const { - if (render_target_) + if (render_ctx_) { - return reinterpret_cast(render_target_->GetSize()); + return reinterpret_cast(render_ctx_->GetSize()); } return Size(); } @@ -384,7 +400,7 @@ void RenderContextImpl::SetCurrentBrush(BrushPtr brush) if (current_brush_ && current_brush_->IsValid()) { - NativePtr::Get(current_brush_)->SetOpacity(brush_opacity_); + NativeObject::Get(current_brush_)->SetOpacity(brush_opacity_); } } @@ -400,30 +416,30 @@ void RenderContextImpl::SetCurrentStrokeStyle(StrokeStylePtr stroke_style) void RenderContextImpl::SetTransform(const Matrix3x2& matrix) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); if (fast_global_transform_) { - render_target_->SetTransform(DX::ConvertToMatrix3x2F(&matrix)); + render_ctx_->SetTransform(DX::ConvertToMatrix3x2F(&matrix)); } else { Matrix3x2 result = matrix * global_transform_; - render_target_->SetTransform(DX::ConvertToMatrix3x2F(&result)); + render_ctx_->SetTransform(DX::ConvertToMatrix3x2F(&result)); } } void RenderContextImpl::SetAntialiasMode(bool enabled) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); - render_target_->SetAntialiasMode(enabled ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED); + render_ctx_->SetAntialiasMode(enabled ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED); antialias_ = enabled; } void RenderContextImpl::SetTextAntialiasMode(TextAntialiasMode mode) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); D2D1_TEXT_ANTIALIAS_MODE antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE; switch (mode) @@ -445,12 +461,12 @@ void RenderContextImpl::SetTextAntialiasMode(TextAntialiasMode mode) } text_antialias_ = mode; - render_target_->SetTextAntialiasMode(antialias_mode); + render_ctx_->SetTextAntialiasMode(antialias_mode); } bool RenderContextImpl::CheckVisibility(const Rect& bounds, const Matrix3x2& transform) { - KGE_ASSERT(render_target_ && "Render target has not been initialized!"); + KGE_ASSERT(render_ctx_ && "Render target has not been initialized!"); if (fast_global_transform_) { @@ -470,7 +486,7 @@ void RenderContextImpl::SaveDrawingState() if (drawing_state_) { - render_target_->SaveDrawingState(drawing_state_.Get()); + render_ctx_->SaveDrawingState(drawing_state_.Get()); } } @@ -480,8 +496,10 @@ void RenderContextImpl::RestoreDrawingState() if (drawing_state_) { - render_target_->RestoreDrawingState(drawing_state_.Get()); + render_ctx_->RestoreDrawingState(drawing_state_.Get()); } } +} // namespace directx +} // namespace graphics } // namespace kiwano diff --git a/src/kiwano/render/DirectX/RenderContextImpl.h b/src/kiwano/render/DirectX/RenderContextImpl.h index cc5da0b6..d09b73a1 100644 --- a/src/kiwano/render/DirectX/RenderContextImpl.h +++ b/src/kiwano/render/DirectX/RenderContextImpl.h @@ -24,7 +24,10 @@ namespace kiwano { - +namespace graphics +{ +namespace directx +{ KGE_DECLARE_SMART_PTR(RenderContextImpl); class KGE_API RenderContextImpl : public RenderContext @@ -34,12 +37,14 @@ public: virtual ~RenderContextImpl(); - HRESULT CreateDeviceResources(ComPtr factory, ComPtr render_target); + HRESULT CreateDeviceResources(ComPtr factory, ComPtr ctx); void BeginDraw() override; void EndDraw() override; + void CreateTexture(Texture& texture, const PixelSize& size) override; + void DrawTexture(const Texture& texture, const Rect* src_rect, const Rect* dest_rect) override; void DrawTextLayout(const TextLayout& layout, const Point& offset, BrushPtr outline_brush) override; @@ -62,8 +67,6 @@ public: void FillEllipse(const Point& center, const Vec2& radius) override; - void CreateTexture(Texture& texture, math::Vec2T size) override; - void PushClipRect(const Rect& clip_rect) override; void PopClipRect() override; @@ -92,6 +95,8 @@ public: void Resize(const Size& size) override; + TexturePtr GetTarget() const override; + private: void DiscardDeviceResources(); @@ -101,8 +106,10 @@ private: private: ComPtr text_renderer_; - ComPtr render_target_; + ComPtr render_ctx_; ComPtr drawing_state_; }; +} // namespace directx +} // namespace graphics } // namespace kiwano diff --git a/src/kiwano/render/DirectX/RendererImpl.cpp b/src/kiwano/render/DirectX/RendererImpl.cpp index 179aefa6..c68cd75d 100644 --- a/src/kiwano/render/DirectX/RendererImpl.cpp +++ b/src/kiwano/render/DirectX/RendererImpl.cpp @@ -20,11 +20,11 @@ #include #include +#include #include #include #include #include -#include #define KGE_SET_STATUS_IF_FAILED(ERRCODE, OBJ, MESSAGE) \ if (FAILED(ERRCODE)) \ @@ -37,24 +37,24 @@ namespace kiwano using namespace kiwano::graphics::directx; -inline const GUID& ConvertPixelFormat(PixelFormat format, UINT& stride) +inline DXGI_FORMAT ConvertPixelFormat(PixelFormat format, UINT32& pitch) { switch (format) { - case PixelFormat::Bpp32RGB: - stride = 3; - return GUID_WICPixelFormat32bppRGB; + //case PixelFormat::Bpp32RGB: + // pitch = 4; + // return DXGI_FORMAT_R8G8B8X8_UNORM; case PixelFormat::Bpp32RGBA: - stride = 4; - return GUID_WICPixelFormat32bppRGBA; + pitch = 4; + return DXGI_FORMAT_R8G8B8A8_UNORM; case PixelFormat::Bpp32BGR: - stride = 3; - return GUID_WICPixelFormat32bppBGR; + pitch = 4; + return DXGI_FORMAT_B8G8R8X8_UNORM; case PixelFormat::Bpp32BGRA: - stride = 4; - return GUID_WICPixelFormat32bppBGRA; + pitch = 4; + return DXGI_FORMAT_B8G8R8A8_UNORM; default: - return GUID_WICPixelFormatDontCare; + return DXGI_FORMAT_UNKNOWN; } } @@ -258,7 +258,7 @@ void RendererImpl::CreateTexture(Texture& texture, const String& file_path) if (SUCCEEDED(hr)) { - NativePtr::Set(texture, bitmap); + NativeObject::Set(texture, bitmap); texture.SetSize({ bitmap->GetSize().width, bitmap->GetSize().height }); texture.SetSizeInPixels({ bitmap->GetPixelSize().width, bitmap->GetPixelSize().height }); @@ -307,7 +307,7 @@ void RendererImpl::CreateTexture(Texture& texture, const BinaryData& data) if (SUCCEEDED(hr)) { - NativePtr::Set(texture, bitmap); + NativeObject::Set(texture, bitmap); texture.SetSize({ bitmap->GetSize().width, bitmap->GetSize().height }); texture.SetSizeInPixels({ bitmap->GetPixelSize().width, bitmap->GetPixelSize().height }); @@ -335,34 +335,19 @@ void RendererImpl::CreateTexture(Texture& texture, const PixelSize& size, const if (SUCCEEDED(hr)) { - UINT stride = 0; - const auto& wicFormat = ConvertPixelFormat(format, stride); - - ComPtr source; - hr = d2d_res_->CreateBitmapSourceFromMemory(source, UINT(size.x), UINT(size.y), UINT(size.x) * stride, - UINT(data.size), reinterpret_cast(data.buffer), - wicFormat); + ComPtr output; + UINT32 pitch = 0; + const auto dxgi_format = ConvertPixelFormat(format, pitch); + hr = d2d_res_->GetDeviceContext()->CreateBitmap( + DX::ConvertToSizeU(size), data.buffer, UINT(size.x) * pitch, + D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET, D2D1::PixelFormat(dxgi_format)), &output); if (SUCCEEDED(hr)) { - ComPtr converter; - hr = d2d_res_->CreateBitmapConverter(converter, source, GUID_WICPixelFormat32bppPBGRA, - WICBitmapDitherTypeNone, nullptr, 0.f, - WICBitmapPaletteTypeMedianCut); + NativeObject::Set(texture, output); - if (SUCCEEDED(hr)) - { - ComPtr bitmap; - hr = d2d_res_->CreateBitmapFromConverter(bitmap, nullptr, converter); - - if (SUCCEEDED(hr)) - { - NativePtr::Set(texture, bitmap); - - texture.SetSize({ bitmap->GetSize().width, bitmap->GetSize().height }); - texture.SetSizeInPixels({ bitmap->GetPixelSize().width, bitmap->GetPixelSize().height }); - } - } + texture.SetSize({ output->GetSize().width, output->GetSize().height }); + texture.SetSizeInPixels({ output->GetPixelSize().width, output->GetPixelSize().height }); } } } @@ -395,7 +380,7 @@ void RendererImpl::CreateGifImage(GifImage& gif, const String& file_path) if (SUCCEEDED(hr)) { - NativePtr::Set(gif, decoder); + NativeObject::Set(gif, decoder); } } @@ -421,7 +406,7 @@ void RendererImpl::CreateGifImage(GifImage& gif, const BinaryData& data) if (SUCCEEDED(hr)) { - NativePtr::Set(gif, decoder); + NativeObject::Set(gif, decoder); } } } @@ -437,7 +422,7 @@ void RendererImpl::CreateGifImageFrame(GifImage::Frame& frame, const GifImage& g hr = E_UNEXPECTED; } - auto decoder = NativePtr::Get(gif); + auto decoder = NativeObject::Get(gif); if (!decoder) { @@ -464,7 +449,7 @@ void RendererImpl::CreateGifImageFrame(GifImage::Frame& frame, const GifImage& g if (SUCCEEDED(hr)) { frame.texture = MakePtr(); - NativePtr::Set(frame.texture, bitmap); + NativeObject::Set(frame.texture, bitmap); frame.texture->SetSize({ bitmap->GetSize().width, bitmap->GetSize().height }); frame.texture->SetSizeInPixels({ bitmap->GetPixelSize().width, bitmap->GetPixelSize().height }); @@ -618,7 +603,7 @@ void RendererImpl::CreateFontCollection(Font& font, Vector& family_names if (SUCCEEDED(hr)) { d2d_res_->GetFontFamilyNames(family_names, font_collection); // ignore the result - NativePtr::Set(font, font_collection); + NativeObject::Set(font, font_collection); } } @@ -641,7 +626,7 @@ void RendererImpl::CreateFontCollection(Font& font, Vector& family_names if (SUCCEEDED(hr)) { d2d_res_->GetFontFamilyNames(family_names, font_collection); // ignore the result - NativePtr::Set(font, font_collection); + NativeObject::Set(font, font_collection); } } @@ -675,7 +660,7 @@ void RendererImpl::CreateTextLayout(TextLayout& layout, const String& content, c auto font_weight = DWRITE_FONT_WEIGHT(font->GetWeight()); auto font_style = DWRITE_FONT_STYLE(font->GetPosture()); auto font_stretch = DWRITE_FONT_STRETCH(font->GetStretch()); - auto collection = NativePtr::Get(font); + auto collection = NativeObject::Get(font); WideString font_family; @@ -698,7 +683,7 @@ void RendererImpl::CreateTextLayout(TextLayout& layout, const String& content, c if (SUCCEEDED(hr)) { - NativePtr::Set(layout, output); + NativeObject::Set(layout, output); layout.SetDirtyFlag(TextLayout::DirtyFlag::Dirty); } } @@ -735,7 +720,7 @@ void RendererImpl::CreateLineShape(Shape& shape, const Point& begin_pos, const P if (SUCCEEDED(hr)) { - NativePtr::Set(shape, path_geo); + NativeObject::Set(shape, path_geo); } } } @@ -759,7 +744,7 @@ void RendererImpl::CreateRectShape(Shape& shape, const Rect& rect) if (SUCCEEDED(hr)) { - NativePtr::Set(shape, output); + NativeObject::Set(shape, output); } KGE_SET_STATUS_IF_FAILED(hr, shape, "Create ID2D1RectangleGeometry failed"); @@ -782,7 +767,7 @@ void RendererImpl::CreateRoundedRectShape(Shape& shape, const Rect& rect, const if (SUCCEEDED(hr)) { - NativePtr::Set(shape, output); + NativeObject::Set(shape, output); } KGE_SET_STATUS_IF_FAILED(hr, shape, "Create ID2D1RoundedRectangleGeometry failed"); @@ -805,7 +790,7 @@ void RendererImpl::CreateEllipseShape(Shape& shape, const Point& center, const V if (SUCCEEDED(hr)) { - NativePtr::Set(shape, output); + NativeObject::Set(shape, output); } KGE_SET_STATUS_IF_FAILED(hr, shape, "Create ID2D1EllipseGeometry failed"); @@ -828,7 +813,7 @@ void RendererImpl::CreateShapeSink(ShapeMaker& maker) if (SUCCEEDED(hr)) { ShapePtr shape = MakePtr(); - NativePtr::Set(shape, geometry); + NativeObject::Set(shape, geometry); maker.SetShape(shape); } @@ -850,7 +835,7 @@ void RendererImpl::CreateBrush(Brush& brush, const Color& color) if (brush.GetType() == Brush::Type::SolidColor && brush.IsValid()) { - hr = NativePtr::Get(brush)->QueryInterface(&solid_brush); + hr = NativeObject::Get(brush)->QueryInterface(&solid_brush); if (SUCCEEDED(hr)) { solid_brush->SetColor(DX::ConvertToColorF(color)); @@ -862,7 +847,7 @@ void RendererImpl::CreateBrush(Brush& brush, const Color& color) if (SUCCEEDED(hr)) { - NativePtr::Set(brush, solid_brush); + NativeObject::Set(brush, solid_brush); } } } @@ -894,7 +879,7 @@ void RendererImpl::CreateBrush(Brush& brush, const LinearGradientStyle& style) if (SUCCEEDED(hr)) { - NativePtr::Set(brush, output); + NativeObject::Set(brush, output); } } } @@ -927,7 +912,7 @@ void RendererImpl::CreateBrush(Brush& brush, const RadialGradientStyle& style) if (SUCCEEDED(hr)) { - NativePtr::Set(brush, output); + NativeObject::Set(brush, output); } } } @@ -945,7 +930,7 @@ void RendererImpl::CreateBrush(Brush& brush, TexturePtr texture) if (SUCCEEDED(hr)) { - auto bitmap = NativePtr::Get(texture); + auto bitmap = NativeObject::Get(texture); if (SUCCEEDED(hr)) { @@ -954,7 +939,7 @@ void RendererImpl::CreateBrush(Brush& brush, TexturePtr texture) if (SUCCEEDED(hr)) { - NativePtr::Set(brush, output); + NativeObject::Set(brush, output); } } } @@ -994,55 +979,60 @@ void RendererImpl::CreateStrokeStyle(StrokeStyle& stroke_style) if (SUCCEEDED(hr)) { - NativePtr::Set(stroke_style, output); + NativeObject::Set(stroke_style, output); } } KGE_SET_STATUS_IF_FAILED(hr, stroke_style, "Create ID2D1StrokeStyle failed"); } -RenderContextPtr RendererImpl::CreateTextureRenderContext(Texture& texture, const Size* desired_size) +RenderContextPtr RendererImpl::CreateTextureRenderContext(TexturePtr texture, const PixelSize& desired_size) { - RenderContextImplPtr ptr = MakePtr(); - HRESULT hr = S_OK; if (!d2d_res_) { hr = E_UNEXPECTED; } + else if (texture == nullptr) + { + hr = E_INVALIDARG; + } if (SUCCEEDED(hr)) { - ComPtr bitmap_rt; + RenderContextImplPtr ptr = MakePtr(); - if (desired_size) + ComPtr render_ctx; + hr = d2d_res_->GetDevice()->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, + &render_ctx); + + if (SUCCEEDED(hr)) { - hr = d2d_res_->GetDeviceContext()->CreateCompatibleRenderTarget(DX::ConvertToSizeF(*desired_size), - &bitmap_rt); - } - else - { - hr = d2d_res_->GetDeviceContext()->CreateCompatibleRenderTarget(&bitmap_rt); + hr = ptr->CreateDeviceResources(d2d_res_->GetFactory(), render_ctx); } if (SUCCEEDED(hr)) { - hr = ptr->CreateDeviceResources(d2d_res_->GetFactory(), bitmap_rt); - } + ComPtr output; + hr = render_ctx->CreateBitmap( + DX::ConvertToSizeU(desired_size), nullptr, 0, + D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET, + D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED)), + &output); - if (SUCCEEDED(hr)) - { - ComPtr output; - hr = bitmap_rt->GetBitmap(&output); if (SUCCEEDED(hr)) { - NativePtr::Set(texture, output); + render_ctx->SetTarget(output.Get()); + NativeObject::Set(texture, output); + + texture->SetSize({ output->GetSize().width, output->GetSize().height }); + texture->SetSizeInPixels({ output->GetPixelSize().width, output->GetPixelSize().height }); + return ptr; } } } - if (SUCCEEDED(hr)) - return ptr; + KGE_THROW_IF_FAILED(hr, "Create render context failed"); return nullptr; } @@ -1056,7 +1046,7 @@ void RendererImpl::Resize(uint32_t width, uint32_t height) if (SUCCEEDED(hr)) { // Clear resources - d2d_res_->SetTargetBitmap(nullptr); + d2d_res_->GetDeviceContext()->SetTarget(nullptr); } if (SUCCEEDED(hr)) diff --git a/src/kiwano/render/DirectX/RendererImpl.h b/src/kiwano/render/DirectX/RendererImpl.h index b57bd811..a0eae5ca 100644 --- a/src/kiwano/render/DirectX/RendererImpl.h +++ b/src/kiwano/render/DirectX/RendererImpl.h @@ -36,7 +36,7 @@ public: void CreateTexture(Texture& texture, const BinaryData& data) override; - void CreateTexture(Texture& texture, const PixelSize& size, const BinaryData& data, PixelFormat format); + void CreateTexture(Texture& texture, const PixelSize& size, const BinaryData& data, PixelFormat format) override; void CreateGifImage(GifImage& gif, const String& file_path) override; @@ -70,7 +70,7 @@ public: void CreateStrokeStyle(StrokeStyle& stroke_style) override; - RenderContextPtr CreateTextureRenderContext(Texture& texture, const Size* desired_size = nullptr) override; + RenderContextPtr CreateTextureRenderContext(TexturePtr texture, const PixelSize& desired_size) override; public: void Clear() override; diff --git a/src/kiwano/render/DirectX/TextDrawingEffect.cpp b/src/kiwano/render/DirectX/TextDrawingEffect.cpp index d3d891fd..13b4bd48 100644 --- a/src/kiwano/render/DirectX/TextDrawingEffect.cpp +++ b/src/kiwano/render/DirectX/TextDrawingEffect.cpp @@ -23,6 +23,10 @@ namespace kiwano { +namespace graphics +{ +namespace directx +{ class TextDrawingEffect : public ITextDrawingEffect { public: @@ -39,8 +43,8 @@ public: virtual ULONG STDMETHODCALLTYPE Release(); private: - unsigned long cRefCount_; - ComPtr pFactory_; + unsigned long cRefCount_; + ComPtr pFactory_; // Outline geometry cache Map, ComPtr> outlineCache_; @@ -194,4 +198,6 @@ STDMETHODIMP TextDrawingEffect::QueryInterface(REFIID riid, void** ppvObject) return S_OK; } +} // namespace directx +} // namespace graphics } // namespace kiwano diff --git a/src/kiwano/render/DirectX/TextDrawingEffect.h b/src/kiwano/render/DirectX/TextDrawingEffect.h index 81fb1217..05f6280c 100644 --- a/src/kiwano/render/DirectX/TextDrawingEffect.h +++ b/src/kiwano/render/DirectX/TextDrawingEffect.h @@ -24,8 +24,12 @@ namespace kiwano { - -interface DWRITE_DECLARE_INTERFACE("7431F439-6E54-4707-A0DC-1AA035D6AFB8") ITextDrawingEffect : public IUnknown +namespace graphics +{ +namespace directx +{ +interface DWRITE_DECLARE_INTERFACE("7431F439-6E54-4707-A0DC-1AA035D6AFB8") ITextDrawingEffect + : public IUnknown { public: static HRESULT Create(_Out_ ITextDrawingEffect** ppTextDrawingEffect, _In_ ID2D1Factory* pFactory); @@ -33,4 +37,6 @@ public: STDMETHOD(CreateOutlineGeomerty) (_Out_ ID2D1Geometry** ppOutlineGeo, _In_ DWRITE_GLYPH_RUN const* glyphRun, float fOriginX, float fOriginY) PURE; }; +} // namespace directx +} // namespace graphics } // namespace kiwano diff --git a/src/kiwano/render/DirectX/TextRenderer.cpp b/src/kiwano/render/DirectX/TextRenderer.cpp index 8329f965..718ef9ed 100644 --- a/src/kiwano/render/DirectX/TextRenderer.cpp +++ b/src/kiwano/render/DirectX/TextRenderer.cpp @@ -23,6 +23,10 @@ namespace kiwano { +namespace graphics +{ +namespace directx +{ class TextRenderer : public ITextRenderer { public: @@ -30,7 +34,7 @@ public: ~TextRenderer(); - STDMETHOD(CreateDeviceResources)(_In_ ID2D1RenderTarget* pRT); + STDMETHOD(CreateDeviceResources)(_In_ ID2D1DeviceContext* pContext); STDMETHOD(DrawTextLayout) (_In_ IDWriteTextLayout* pTextLayout, float fOriginX, float fOriginY, _In_opt_ ID2D1Brush* pDefaultFillBrush, @@ -67,17 +71,17 @@ public: HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); private: - unsigned long cRefCount_; - uint32_t cPrimitivesCount_; - float fDefaultOutlineWidth_; - ComPtr pFactory_; - ComPtr pRT_; - ComPtr pDefaultFillBrush_; - ComPtr pDefaultOutlineBrush_; - ComPtr pDefaultStrokeStyle_; + unsigned long cRefCount_; + uint32_t cPrimitivesCount_; + float fDefaultOutlineWidth_; + ComPtr pFactory_; + ComPtr pContext_; + ComPtr pDefaultFillBrush_; + ComPtr pDefaultOutlineBrush_; + ComPtr pDefaultStrokeStyle_; }; -HRESULT ITextRenderer::Create(_Out_ ITextRenderer** ppTextRenderer, _In_ ID2D1RenderTarget* pRT) +HRESULT ITextRenderer::Create(_Out_ ITextRenderer** ppTextRenderer, _In_ ID2D1DeviceContext* pContext) { HRESULT hr = E_FAIL; @@ -86,7 +90,7 @@ HRESULT ITextRenderer::Create(_Out_ ITextRenderer** ppTextRenderer, _In_ ID2D1Re TextRenderer* pTextRenderer = new (std::nothrow) TextRenderer; if (pTextRenderer) { - hr = pTextRenderer->CreateDeviceResources(pRT); + hr = pTextRenderer->CreateDeviceResources(pContext); if (SUCCEEDED(hr)) { @@ -115,17 +119,17 @@ TextRenderer::TextRenderer() TextRenderer::~TextRenderer() {} -STDMETHODIMP TextRenderer::CreateDeviceResources(_In_ ID2D1RenderTarget* pRT) +STDMETHODIMP TextRenderer::CreateDeviceResources(_In_ ID2D1DeviceContext* pContext) { HRESULT hr = E_FAIL; pFactory_.Reset(); - pRT_.Reset(); + pContext_.Reset(); - if (pRT) + if (pContext) { - pRT_ = pRT; - pRT_->GetFactory(&pFactory_); + pContext_ = pContext; + pContext_->GetFactory(&pFactory_); hr = S_OK; } return hr; @@ -152,7 +156,7 @@ STDMETHODIMP TextRenderer::DrawTextLayout(_In_ IDWriteTextLayout* pTextLayout, f STDMETHODIMP TextRenderer::DrawGlyphRun(__maybenull void* clientDrawingContext, float baselineOriginX, float baselineOriginY, DWRITE_MEASURING_MODE measuringMode, - __in DWRITE_GLYPH_RUN const* glyphRun, + __in DWRITE_GLYPH_RUN const* glyphRun, __in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription, IUnknown* clientDrawingEffect) { @@ -176,8 +180,8 @@ STDMETHODIMP TextRenderer::DrawGlyphRun(__maybenull void* clientDrawingContext, if (SUCCEEDED(hr)) { - pRT_->DrawGeometry(pOutlineGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_, - pDefaultStrokeStyle_.Get()); + pContext_->DrawGeometry(pOutlineGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_, + pDefaultStrokeStyle_.Get()); ++cPrimitivesCount_; } @@ -187,7 +191,8 @@ STDMETHODIMP TextRenderer::DrawGlyphRun(__maybenull void* clientDrawingContext, { if (SUCCEEDED(hr)) { - pRT_->DrawGlyphRun(D2D1::Point2F(baselineOriginX, baselineOriginY), glyphRun, pDefaultFillBrush_.Get()); + pContext_->DrawGlyphRun(D2D1::Point2F(baselineOriginX, baselineOriginY), glyphRun, + pDefaultFillBrush_.Get()); ++cPrimitivesCount_; } @@ -236,15 +241,15 @@ STDMETHODIMP TextRenderer::DrawUnderline(__maybenull void* clientDrawingContext, if (SUCCEEDED(hr) && pDefaultOutlineBrush_) { - pRT_->DrawGeometry(pTransformedGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_, - pDefaultStrokeStyle_.Get()); + pContext_->DrawGeometry(pTransformedGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_, + pDefaultStrokeStyle_.Get()); ++cPrimitivesCount_; } if (SUCCEEDED(hr) && pCurrentFillBrush) { - pRT_->FillGeometry(pTransformedGeometry.Get(), pCurrentFillBrush.Get()); + pContext_->FillGeometry(pTransformedGeometry.Get(), pCurrentFillBrush.Get()); ++cPrimitivesCount_; } @@ -292,15 +297,15 @@ STDMETHODIMP TextRenderer::DrawStrikethrough(__maybenull void* clientDrawingCont if (SUCCEEDED(hr) && pDefaultOutlineBrush_) { - pRT_->DrawGeometry(pTransformedGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_, - pDefaultStrokeStyle_.Get()); + pContext_->DrawGeometry(pTransformedGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_, + pDefaultStrokeStyle_.Get()); ++cPrimitivesCount_; } if (SUCCEEDED(hr) && pCurrentFillBrush) { - pRT_->FillGeometry(pTransformedGeometry.Get(), pCurrentFillBrush.Get()); + pContext_->FillGeometry(pTransformedGeometry.Get(), pCurrentFillBrush.Get()); ++cPrimitivesCount_; } @@ -333,7 +338,7 @@ STDMETHODIMP TextRenderer::GetCurrentTransform(__maybenull void* clientDrawingCo { KGE_NOT_USED(clientDrawingContext); - pRT_->GetTransform(reinterpret_cast(transform)); + pContext_->GetTransform(reinterpret_cast(transform)); return S_OK; } @@ -343,7 +348,7 @@ STDMETHODIMP TextRenderer::GetPixelsPerDip(__maybenull void* clientDrawingContex float x, yUnused; - pRT_->GetDpi(&x, &yUnused); + pContext_->GetDpi(&x, &yUnused); *pixelsPerDip = x / 96; return S_OK; @@ -400,4 +405,6 @@ STDMETHODIMP TextRenderer::QueryInterface(REFIID riid, void** ppvObject) return S_OK; } +} // namespace directx +} // namespace graphics } // namespace kiwano diff --git a/src/kiwano/render/DirectX/TextRenderer.h b/src/kiwano/render/DirectX/TextRenderer.h index 15c47347..63b8e8b4 100644 --- a/src/kiwano/render/DirectX/TextRenderer.h +++ b/src/kiwano/render/DirectX/TextRenderer.h @@ -23,16 +23,23 @@ namespace kiwano { -interface DWRITE_DECLARE_INTERFACE("b293e798-9916-4096-a3c1-e5d4039dfa64") ITextRenderer : public IDWriteTextRenderer +namespace graphics +{ +namespace directx +{ +interface DWRITE_DECLARE_INTERFACE("b293e798-9916-4096-a3c1-e5d4039dfa64") ITextRenderer + : public IDWriteTextRenderer { public: - static KGE_API HRESULT Create(_Out_ ITextRenderer** ppTextRenderer, _In_ ID2D1RenderTarget* pRT); + static KGE_API HRESULT Create(_Out_ ITextRenderer** ppTextRenderer, _In_ ID2D1DeviceContext* pContext); STDMETHOD(DrawTextLayout) - (_In_ IDWriteTextLayout * pTextLayout, float fOriginX, float fOriginY, _In_opt_ ID2D1Brush* pDefaultFillBrush, + (_In_ IDWriteTextLayout* pTextLayout, float fOriginX, float fOriginY, _In_opt_ ID2D1Brush* pDefaultFillBrush, _In_opt_ ID2D1Brush* pDefaultOutlineBrush, float fDefaultOutlineWidth, _In_opt_ ID2D1StrokeStyle* pDefaultStrokeStyle) PURE; STDMETHOD_(uint32_t, GetLastPrimitivesCount)() PURE; }; +} // namespace directx +} // namespace graphics } // namespace kiwano diff --git a/src/kiwano/render/DirectX/helper.h b/src/kiwano/render/DirectX/helper.h index 51ef440e..44244d4e 100644 --- a/src/kiwano/render/DirectX/helper.h +++ b/src/kiwano/render/DirectX/helper.h @@ -23,8 +23,7 @@ #include #include #include -#include -#include +#include namespace kiwano { @@ -76,7 +75,7 @@ inline D2D1_POINT_2F* ConvertToPoint2F(Vec2* vec2) } // -// SizeF +// Size // inline const D2D1_SIZE_F& ConvertToSizeF(const Vec2& vec2) @@ -99,6 +98,26 @@ inline D2D1_SIZE_F* ConvertToSizeF(Vec2* vec2) return reinterpret_cast(vec2); } +inline const D2D1_SIZE_U& ConvertToSizeU(const math::Vec2T& vec2) +{ + return reinterpret_cast(vec2); +} + +inline D2D1_SIZE_U& ConvertToSizeU(math::Vec2T& vec2) +{ + return reinterpret_cast(vec2); +} + +inline const D2D1_SIZE_U* ConvertToSizeU(const math::Vec2T* vec2) +{ + return reinterpret_cast(vec2); +} + +inline D2D1_SIZE_U* ConvertToSizeU(math::Vec2T* vec2) +{ + return reinterpret_cast(vec2); +} + // // RectF // diff --git a/src/kiwano/render/Font.h b/src/kiwano/render/Font.h index 2ab760bd..11081c24 100644 --- a/src/kiwano/render/Font.h +++ b/src/kiwano/render/Font.h @@ -19,8 +19,8 @@ // THE SOFTWARE. #pragma once -#include #include +#include namespace kiwano { diff --git a/src/kiwano/render/GifImage.cpp b/src/kiwano/render/GifImage.cpp index d3af8a95..055bb8b7 100644 --- a/src/kiwano/render/GifImage.cpp +++ b/src/kiwano/render/GifImage.cpp @@ -116,14 +116,13 @@ GifImage::Frame GifImage::GetFrame(uint32_t index) } // namespace kiwano #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX -#include namespace kiwano { bool GifImage::GetGlobalMetadata() { - ComPtr decoder = NativePtr::Get(this); + ComPtr decoder = NativeObject::Get(this); HRESULT hr = decoder ? S_OK : E_FAIL; diff --git a/src/kiwano/render/NativeObject.cpp b/src/kiwano/render/NativeObject.cpp index fa43030d..7c3f01a6 100644 --- a/src/kiwano/render/NativeObject.cpp +++ b/src/kiwano/render/NativeObject.cpp @@ -17,10 +17,7 @@ void NativeObjectBase::ResetNativePointer(void* native_pointer) native_pointer_ = native_pointer; } -// -// NativeObject for Windows -// -#if defined(KGE_PLATFORM_WINDOWS) +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX NativeObject::~NativeObject() { diff --git a/src/kiwano/render/NativeObject.h b/src/kiwano/render/NativeObject.h index b5a1086d..eebeac0a 100644 --- a/src/kiwano/render/NativeObject.h +++ b/src/kiwano/render/NativeObject.h @@ -57,7 +57,7 @@ protected: void* native_pointer_; }; -#if defined(KGE_PLATFORM_WINDOWS) +#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX class KGE_API NativeObject : public NativeObjectBase { @@ -65,6 +65,52 @@ public: virtual ~NativeObject(); void ResetNativePointer(void* native_pointer = nullptr) override; + + template ::value, int>::type> + static inline ComPtr<_Ty> Get(const NativeObject* object) + { + if (object) + { + ComPtr ptr = object->GetNativePointer(); + if (ptr) + { + ComPtr<_Ty> native; + if (SUCCEEDED(ptr->QueryInterface<_Ty>(&native))) + return native; + } + } + return nullptr; + } + + template + static inline ComPtr<_Ty> Get(const NativeObject& object) + { + return NativeObject::Get<_Ty>(&object); + } + + template + static inline ComPtr<_Ty> Get(NativeObjectPtr object) + { + return NativeObject::Get<_Ty>(object.Get()); + } + + static inline void Set(NativeObject* object, ComPtr com_ptr) + { + if (object) + { + object->ResetNativePointer(com_ptr.Get()); + } + } + + static inline void Set(NativeObject& object, ComPtr com_ptr) + { + NativeObject::Set(&object, com_ptr); + } + + static inline void Set(NativeObjectPtr object, ComPtr com_ptr) + { + NativeObject::Set(object.Get(), com_ptr); + } }; #else diff --git a/src/kiwano/render/RenderContext.cpp b/src/kiwano/render/RenderContext.cpp index a305c6c3..4342945d 100644 --- a/src/kiwano/render/RenderContext.cpp +++ b/src/kiwano/render/RenderContext.cpp @@ -24,14 +24,9 @@ namespace kiwano { -RenderContextPtr RenderContext::Create(Texture& texture) +RenderContextPtr RenderContext::Create(TexturePtr texture, const PixelSize& size) { - return Renderer::GetInstance().CreateTextureRenderContext(texture, nullptr); -} - -RenderContextPtr RenderContext::Create(Texture& texture, const Size& size) -{ - return Renderer::GetInstance().CreateTextureRenderContext(texture, &size); + return Renderer::GetInstance().CreateTextureRenderContext(texture, size); } RenderContext::RenderContext() diff --git a/src/kiwano/render/RenderContext.h b/src/kiwano/render/RenderContext.h index 29a047ee..046ed54c 100644 --- a/src/kiwano/render/RenderContext.h +++ b/src/kiwano/render/RenderContext.h @@ -52,16 +52,11 @@ enum class TextAntialiasMode class KGE_API RenderContext : public NativeObject { public: - /// \~chinese - /// @brief 创建纹理渲染上下文,将绘制结果输出到纹理中 - /// @param texture 保存绘制结果的纹理 - static RenderContextPtr Create(Texture& texture); - /// \~chinese /// @brief 创建纹理渲染上下文,将绘制结果输出到纹理中 /// @param texture 保存绘制结果的纹理 /// @param size 渲染输出大小 - static RenderContextPtr Create(Texture& texture, const Size& size); + static RenderContextPtr Create(TexturePtr texture, const PixelSize& size); /// \~chinese /// @brief 开始渲染 @@ -71,6 +66,12 @@ public: /// @brief 结束渲染 virtual void EndDraw(); + /// \~chinese + /// @brief 创建空纹理 + /// @param[out] texture 输出纹理 + /// @param[in] size 纹理像素大小 + virtual void CreateTexture(Texture& texture, const PixelSize& size) = 0; + /// \~chinese /// @brief 绘制纹理 /// @param texture 纹理 @@ -148,12 +149,6 @@ public: /// @param radius 椭圆半径 virtual void FillEllipse(const Point& center, const Vec2& radius) = 0; - /// \~chinese - /// @brief 创建纹理 - /// @param texture 纹理 - /// @param size 纹理像素大小 - virtual void CreateTexture(Texture& texture, math::Vec2T size) = 0; - /// \~chinese /// @brief 设置绘制的裁剪区域 /// @param clip_rect 裁剪矩形 @@ -237,6 +232,10 @@ public: /// @brief 设置全局二维变换 virtual void SetGlobalTransform(const Matrix3x2* matrix); + /// \~chinese + /// @brief 获取渲染目标 + virtual TexturePtr GetTarget() const = 0; + public: /// \~chinese /// @brief 渲染上下文状态 diff --git a/src/kiwano/render/Renderer.h b/src/kiwano/render/Renderer.h index 25d87311..20436994 100644 --- a/src/kiwano/render/Renderer.h +++ b/src/kiwano/render/Renderer.h @@ -210,7 +210,7 @@ public: /// @param[in,out] texture 渲染输出的纹理 /// @param[in] desired_size 期望的输出大小 /// @return 纹理渲染上下文 - virtual RenderContextPtr CreateTextureRenderContext(Texture& texture, const Size* desired_size = nullptr) = 0; + virtual RenderContextPtr CreateTextureRenderContext(TexturePtr texture, const PixelSize& desired_size) = 0; public: /// \~chinese diff --git a/src/kiwano/render/Shape.cpp b/src/kiwano/render/Shape.cpp index c20d7dbf..8833b27b 100644 --- a/src/kiwano/render/Shape.cpp +++ b/src/kiwano/render/Shape.cpp @@ -22,10 +22,6 @@ #include #include -#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX -#include -#endif - namespace kiwano { @@ -40,7 +36,7 @@ Rect Shape::GetBoundingBox() const { #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX Rect bounds; - auto geometry = NativePtr::Get(this); + auto geometry = NativeObject::Get(this); if (geometry) { // no matter it failed or not @@ -56,7 +52,7 @@ Rect Shape::GetBoundingBox(const Matrix3x2& transform) const { #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX Rect bounds; - auto geometry = NativePtr::Get(this); + auto geometry = NativeObject::Get(this); if (geometry) { // no matter it failed or not @@ -72,7 +68,7 @@ float Shape::GetLength() const { #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX float length = 0.f; - auto geometry = NativePtr::Get(this); + auto geometry = NativeObject::Get(this); if (geometry) { // no matter it failed or not @@ -87,7 +83,7 @@ float Shape::GetLength() const bool Shape::ComputePointAtLength(float length, Point& point, Vec2& tangent) const { #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto geometry = NativePtr::Get(this); + auto geometry = NativeObject::Get(this); if (geometry) { HRESULT hr = geometry->ComputePointAtLength(length, D2D1::Matrix3x2F::Identity(), DX::ConvertToPoint2F(&point), @@ -104,7 +100,7 @@ bool Shape::ComputePointAtLength(float length, Point& point, Vec2& tangent) cons float Shape::ComputeArea() const { #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto geometry = NativePtr::Get(this); + auto geometry = NativeObject::Get(this); if (geometry) { float area = 0.f; @@ -120,7 +116,7 @@ float Shape::ComputeArea() const bool Shape::ContainsPoint(const Point& point, const Matrix3x2* transform) const { #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto geometry = NativePtr::Get(this); + auto geometry = NativeObject::Get(this); if (!geometry) return false; diff --git a/src/kiwano/render/ShapeMaker.cpp b/src/kiwano/render/ShapeMaker.cpp index 819e0564..48299ee4 100644 --- a/src/kiwano/render/ShapeMaker.cpp +++ b/src/kiwano/render/ShapeMaker.cpp @@ -21,10 +21,6 @@ #include #include -#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX -#include -#endif - namespace kiwano { @@ -59,7 +55,7 @@ void ShapeMaker::BeginPath(const Point& begin_pos) } #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); native->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); #else // not supported @@ -71,7 +67,7 @@ void ShapeMaker::EndPath(bool closed) KGE_ASSERT(IsStreamOpened()); #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); native->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN); #else // not supported @@ -85,7 +81,7 @@ void ShapeMaker::AddLine(const Point& point) KGE_ASSERT(IsStreamOpened()); #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); native->AddLine(DX::ConvertToPoint2F(point)); #else // not supported @@ -97,7 +93,7 @@ void ShapeMaker::AddLines(const Vector& points) KGE_ASSERT(IsStreamOpened()); #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); native->AddLines(reinterpret_cast(&points[0]), static_cast(points.size())); #else // not supported @@ -109,7 +105,7 @@ void kiwano::ShapeMaker::AddLines(const Point* points, size_t count) KGE_ASSERT(IsStreamOpened()); #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); native->AddLines(reinterpret_cast(points), UINT32(count)); #else // not supported @@ -121,7 +117,7 @@ void ShapeMaker::AddBezier(const Point& point1, const Point& point2, const Point KGE_ASSERT(IsStreamOpened()); #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); native->AddBezier( D2D1::BezierSegment(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2), DX::ConvertToPoint2F(point3))); #else @@ -134,7 +130,7 @@ void ShapeMaker::AddArc(const Point& point, const Size& radius, float rotation, KGE_ASSERT(IsStreamOpened()); #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); native->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)); @@ -151,9 +147,9 @@ ShapePtr ShapeMaker::Combine(ShapePtr shape_a, ShapePtr shape_b, CombineMode mod #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (shape_a && shape_b) { - auto geo_a = NativePtr::Get(shape_a); - auto geo_b = NativePtr::Get(shape_b); - auto native = NativePtr::Get(maker); + auto geo_a = NativeObject::Get(shape_a); + auto geo_b = NativeObject::Get(shape_b); + auto native = NativeObject::Get(maker); HRESULT hr = geo_a->CombineWithGeometry(geo_b.Get(), D2D1_COMBINE_MODE(mode), DX::ConvertToMatrix3x2F(matrix), native.Get()); @@ -176,7 +172,7 @@ void ShapeMaker::OpenStream() Renderer::GetInstance().CreateShapeSink(*this); #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto geometry = NativePtr::Get(shape_); + auto geometry = NativeObject::Get(shape_); if (geometry) { ComPtr native; @@ -184,7 +180,7 @@ void ShapeMaker::OpenStream() HRESULT hr = geometry->Open(&native); if (SUCCEEDED(hr)) { - NativePtr::Set(this, native); + NativeObject::Set(this, native); } KGE_THROW_IF_FAILED(hr, "ID2D1PathGeometry::Open failed"); } @@ -199,7 +195,7 @@ void ShapeMaker::CloseStream() return; #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); HRESULT hr = native->Close(); KGE_THROW_IF_FAILED(hr, "ID2D1PathGeometry::Close failed"); diff --git a/src/kiwano/render/TextLayout.cpp b/src/kiwano/render/TextLayout.cpp index e8ae17bc..da600a64 100644 --- a/src/kiwano/render/TextLayout.cpp +++ b/src/kiwano/render/TextLayout.cpp @@ -21,10 +21,6 @@ #include #include -#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX -#include -#endif - namespace kiwano { @@ -84,7 +80,7 @@ void TextLayout::SetFont(FontPtr font) return; #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); KGE_ASSERT(native); if (native) @@ -93,7 +89,7 @@ void TextLayout::SetFont(FontPtr font) // reset font collection { - auto collection = NativePtr::Get(font); + auto collection = NativeObject::Get(font); hr = native->SetFontCollection(collection.Get(), { 0, content_length_ }); KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontCollection failed"); @@ -148,7 +144,7 @@ void TextLayout::SetFont(FontPtr font) void TextLayout::SetUnderline(bool enable) { #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); KGE_ASSERT(native); if (native) @@ -166,7 +162,7 @@ void TextLayout::SetUnderline(bool enable) void TextLayout::SetStrikethrough(bool enable) { #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); KGE_ASSERT(native); if (native) @@ -184,7 +180,7 @@ void TextLayout::SetStrikethrough(bool enable) void TextLayout::SetAlignment(TextAlign align) { #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); KGE_ASSERT(native); if (native) @@ -219,7 +215,7 @@ void TextLayout::SetAlignment(TextAlign align) void TextLayout::SetWrapWidth(float wrap_width) { #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); KGE_ASSERT(native); if (native) @@ -249,7 +245,7 @@ void TextLayout::SetWrapWidth(float wrap_width) void TextLayout::SetLineSpacing(float line_spacing) { #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); KGE_ASSERT(native); if (native) @@ -284,7 +280,7 @@ bool TextLayout::UpdateIfDirty() line_count_ = 0; size_ = Size(); - auto native = NativePtr::Get(this); + auto native = NativeObject::Get(this); if (content_length_ == 0 || !native) return true; diff --git a/src/kiwano/render/Texture.cpp b/src/kiwano/render/Texture.cpp index 5d70714e..e82f9797 100644 --- a/src/kiwano/render/Texture.cpp +++ b/src/kiwano/render/Texture.cpp @@ -23,10 +23,6 @@ #include #include // std::hash -#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX -#include -#endif - namespace kiwano { @@ -108,8 +104,8 @@ void Texture::CopyFrom(TexturePtr copy_from) #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (IsValid() && copy_from) { - auto native = NativePtr::Get(this); - auto native_to_copy = NativePtr::Get(copy_from); + auto native = NativeObject::Get(this); + auto native_to_copy = NativeObject::Get(copy_from); HRESULT hr = native->CopyFromBitmap(nullptr, native_to_copy.Get(), nullptr); @@ -125,8 +121,8 @@ void Texture::CopyFrom(TexturePtr copy_from, const Rect& src_rect, const Point& #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX if (IsValid() && copy_from) { - auto native = NativePtr::Get(this); - auto native_to_copy = NativePtr::Get(copy_from); + auto native = NativeObject::Get(this); + auto native_to_copy = NativeObject::Get(copy_from); HRESULT hr = native->CopyFromBitmap(&D2D1::Point2U(uint32_t(dest_point.x), uint32_t(dest_point.y)), native_to_copy.Get(), diff --git a/src/kiwano/render/Texture.h b/src/kiwano/render/Texture.h index b420ef5b..3a9a73be 100644 --- a/src/kiwano/render/Texture.h +++ b/src/kiwano/render/Texture.h @@ -54,7 +54,6 @@ typedef math::Vec2T PixelSize; */ enum class PixelFormat { - Bpp32RGB, Bpp32RGBA, Bpp32BGR, Bpp32BGRA,