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