feat: update to direct2d 1.3

This commit is contained in:
Nomango 2023-09-19 20:25:06 +08:00
parent 3596e355cf
commit dc5ec25c00
35 changed files with 427 additions and 456 deletions

View File

@ -96,7 +96,6 @@
<ClInclude Include="..\..\src\kiwano\render\DirectX\D3DDeviceResourcesBase.h" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\D3DDeviceResourcesBase.h" />
<ClInclude Include="..\..\src\kiwano\render\DirectX\FontCollectionLoader.h" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\FontCollectionLoader.h" />
<ClInclude Include="..\..\src\kiwano\render\DirectX\helper.h" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\helper.h" />
<ClInclude Include="..\..\src\kiwano\render\DirectX\NativePtr.h" />
<ClInclude Include="..\..\src\kiwano\render\DirectX\RenderContextImpl.h" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\RenderContextImpl.h" />
<ClInclude Include="..\..\src\kiwano\render\DirectX\RendererImpl.h" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\RendererImpl.h" />
<ClInclude Include="..\..\src\kiwano\render\DirectX\TextRenderer.h" /> <ClInclude Include="..\..\src\kiwano\render\DirectX\TextRenderer.h" />

View File

@ -222,12 +222,6 @@
<ClInclude Include="..\..\src\kiwano\core\IntrusiveList.h"> <ClInclude Include="..\..\src\kiwano\core\IntrusiveList.h">
<Filter>core</Filter> <Filter>core</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\render\NativeObject.h">
<Filter>render</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\DirectX\NativePtr.h">
<Filter>render\DirectX</Filter>
</ClInclude>
<ClInclude Include="..\..\src\kiwano\render\ShapeMaker.h"> <ClInclude Include="..\..\src\kiwano\render\ShapeMaker.h">
<Filter>render</Filter> <Filter>render</Filter>
</ClInclude> </ClInclude>
@ -411,6 +405,9 @@
<ClInclude Include="..\..\src\kiwano\render\DirectX\TextDrawingEffect.h"> <ClInclude Include="..\..\src\kiwano\render\DirectX\TextDrawingEffect.h">
<Filter>render\DirectX</Filter> <Filter>render\DirectX</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\src\kiwano\render\NativeObject.h">
<Filter>render</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp"> <ClCompile Include="..\..\src\kiwano\2d\Canvas.cpp">
@ -608,9 +605,6 @@
<ClCompile Include="..\..\src\kiwano\render\TextStyle.cpp"> <ClCompile Include="..\..\src\kiwano\render\TextStyle.cpp">
<Filter>render</Filter> <Filter>render</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\kiwano\render\NativeObject.cpp">
<Filter>render</Filter>
</ClCompile>
<ClCompile Include="..\..\src\kiwano\core\Duration.cpp"> <ClCompile Include="..\..\src\kiwano\core\Duration.cpp">
<Filter>core</Filter> <Filter>core</Filter>
</ClCompile> </ClCompile>
@ -677,6 +671,9 @@
<ClCompile Include="..\..\src\kiwano\render\DirectX\TextDrawingEffect.cpp"> <ClCompile Include="..\..\src\kiwano\render\DirectX\TextDrawingEffect.cpp">
<Filter>render\DirectX</Filter> <Filter>render\DirectX</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="..\..\src\kiwano\render\NativeObject.cpp">
<Filter>render</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="suppress_warning.ruleset" /> <None Include="suppress_warning.ruleset" />

View File

@ -25,10 +25,9 @@ namespace kiwano
{ {
Canvas::Canvas() Canvas::Canvas()
{ {
RecreateContext(nullptr);
} }
Canvas::Canvas(const Size& size) Canvas::Canvas(const PixelSize& size)
{ {
ResizeAndClear(size); ResizeAndClear(size);
} }
@ -39,24 +38,10 @@ CanvasRenderContextPtr Canvas::GetContext2D() const
return ctx; return ctx;
} }
void Canvas::ResizeAndClear(Size size) void Canvas::ResizeAndClear(const PixelSize& size)
{
RecreateContext(&size);
}
void Canvas::RecreateContext(Size* size)
{ {
texture_cached_ = MakePtr<Texture>(); texture_cached_ = MakePtr<Texture>();
render_ctx_ = RenderContext::Create(texture_cached_, size);
if (size)
{
render_ctx_ = RenderContext::Create(*texture_cached_, *size);
}
else
{
render_ctx_ = RenderContext::Create(*texture_cached_);
}
if (render_ctx_) if (render_ctx_)
{ {
SetSize(render_ctx_->GetSize()); 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) void Canvas::OnRender(RenderContext& ctx)
{ {
if (texture_cached_) if (texture_cached_)

View File

@ -43,12 +43,15 @@ KGE_DECLARE_SMART_PTR(CanvasRenderContext);
class KGE_API Canvas : public Actor class KGE_API Canvas : public Actor
{ {
public: public:
/// \~chinese
/// @brief 创建画布
/// @warning 必须调用 ResizeAndClear 以初始化画布
Canvas(); Canvas();
/// \~chinese /// \~chinese
/// @brief 创建画布 /// @brief 创建画布
/// @param size 画布大小 /// @param size 画布大小
Canvas(const Size& size); Canvas(const PixelSize& size);
/// \~chinese /// \~chinese
/// @brief 获取2D绘图上下文 /// @brief 获取2D绘图上下文
@ -57,17 +60,14 @@ public:
/// \~chinese /// \~chinese
/// @brief 清空画布大小并重设画布大小 /// @brief 清空画布大小并重设画布大小
/// @warning 该函数会导致原绘图上下文失效 /// @warning 该函数会导致原绘图上下文失效
void ResizeAndClear(Size size); void ResizeAndClear(const PixelSize& size);
/// \~chinese /// \~chinese
/// @brief 导出纹理 /// @brief 导出纹理
TexturePtr ExportToTexture() const; TexturePtr GetTexture() const;
void OnRender(RenderContext& ctx) override; void OnRender(RenderContext& ctx) override;
private:
void RecreateContext(Size* size);
private: private:
TexturePtr texture_cached_; TexturePtr texture_cached_;
RenderContextPtr render_ctx_; RenderContextPtr render_ctx_;
@ -285,6 +285,11 @@ private:
/** @} */ /** @} */
inline TexturePtr Canvas::GetTexture() const
{
return texture_cached_;
}
inline void CanvasRenderContext::BeginDraw() inline void CanvasRenderContext::BeginDraw()
{ {
KGE_ASSERT(ctx_); KGE_ASSERT(ctx_);

View File

@ -20,6 +20,7 @@
#include <kiwano/2d/GifSprite.h> #include <kiwano/2d/GifSprite.h>
#include <kiwano/render/RenderContext.h> #include <kiwano/render/RenderContext.h>
#include <kiwano/render/Renderer.h>
namespace kiwano namespace kiwano
{ {
@ -76,9 +77,8 @@ bool GifSprite::Load(GifImagePtr gif)
frame_to_render_.Reset(); frame_to_render_.Reset();
frame_rt_.Reset(); frame_rt_.Reset();
Size frame_size = Size(float(gif_->GetWidthInPixels()), float(gif_->GetHeightInPixels()));
frame_to_render_ = MakePtr<Texture>(); frame_to_render_ = MakePtr<Texture>();
frame_rt_ = RenderContext::Create(*frame_to_render_, frame_size); frame_rt_ = RenderContext::Create(frame_to_render_, gif_->GetSizeInPixels());
if (frame_rt_) if (frame_rt_)
{ {

View File

@ -289,7 +289,8 @@ void TextActor::UpdateCachedTexture()
const auto expectedSize = layout_->GetSize() + cached_texture_offset * 2; const auto expectedSize = layout_->GetSize() + cached_texture_offset * 2;
if (!render_ctx_) 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) else if (render_ctx_->GetSize() != expectedSize)
{ {

View File

@ -100,6 +100,8 @@ set(SOURCE_FILES
math/Transform.hpp math/Transform.hpp
math/Vec2.hpp math/Vec2.hpp
platform/win32/ComPtr.hpp platform/win32/ComPtr.hpp
platform/win32/ComObject.cpp
platform/win32/ComObject.h
platform/win32/libraries.cpp platform/win32/libraries.cpp
platform/win32/libraries.h platform/win32/libraries.h
platform/win32/WindowImpl.cpp platform/win32/WindowImpl.cpp
@ -113,6 +115,8 @@ set(SOURCE_FILES
platform/Runner.h platform/Runner.h
platform/Window.cpp platform/Window.cpp
platform/Window.h platform/Window.h
platform/NativeObject.cpp
platform/NativeObject.h
render/DirectX/D2DDeviceResources.cpp render/DirectX/D2DDeviceResources.cpp
render/DirectX/D2DDeviceResources.h render/DirectX/D2DDeviceResources.h
render/DirectX/D3D10DeviceResources.cpp render/DirectX/D3D10DeviceResources.cpp
@ -123,7 +127,6 @@ set(SOURCE_FILES
render/DirectX/FontCollectionLoader.cpp render/DirectX/FontCollectionLoader.cpp
render/DirectX/FontCollectionLoader.h render/DirectX/FontCollectionLoader.h
render/DirectX/helper.h render/DirectX/helper.h
render/DirectX/NativePtr.h
render/DirectX/RenderContextImpl.cpp render/DirectX/RenderContextImpl.cpp
render/DirectX/RenderContextImpl.h render/DirectX/RenderContextImpl.h
render/DirectX/RendererImpl.cpp render/DirectX/RendererImpl.cpp

View File

@ -22,10 +22,6 @@
#include <kiwano/render/Brush.h> #include <kiwano/render/Brush.h>
#include <kiwano/render/Renderer.h> #include <kiwano/render/Renderer.h>
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
#include <kiwano/render/DirectX/NativePtr.h>
#endif
namespace kiwano namespace kiwano
{ {
GradientStop::GradientStop() GradientStop::GradientStop()
@ -124,7 +120,7 @@ void Brush::SetTransform(const Transform& transform)
void Brush::SetTransform(const Matrix3x2& transform) void Brush::SetTransform(const Matrix3x2& transform)
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<ID2D1Brush>(this); auto native = NativeObject::Get<ID2D1Brush>(this);
KGE_ASSERT(native); KGE_ASSERT(native);
if (native) if (native)

View File

@ -19,8 +19,8 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/render/Color.h>
#include <kiwano/render/NativeObject.h> #include <kiwano/render/NativeObject.h>
#include <kiwano/render/Color.h>
#include <kiwano/render/Texture.h> #include <kiwano/render/Texture.h>
namespace kiwano namespace kiwano

View File

@ -92,8 +92,6 @@ public:
void DiscardResources() override; void DiscardResources() override;
void SetTargetBitmap(_In_ ComPtr<ID2D1Bitmap1> target) override;
void ResetTextRenderingParams(_In_ HMONITOR monitor) override; void ResetTextRenderingParams(_In_ HMONITOR monitor) override;
public: public:
@ -213,7 +211,6 @@ void D2DDeviceResources::DiscardResources()
} }
} }
target_bitmap_.Reset();
device_context_.Reset(); device_context_.Reset();
device_.Reset(); device_.Reset();
@ -315,7 +312,7 @@ HRESULT D2DDeviceResources::CreateDeviceResources(_In_ ComPtr<IDXGIDevice> dxgi_
{ {
ComPtr<ID2D1DeviceContext> device_ctx; ComPtr<ID2D1DeviceContext> 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)) if (SUCCEEDED(hr))
{ {
@ -350,7 +347,7 @@ HRESULT D2DDeviceResources::CreateWindowSizeDependentResources()
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
SetTargetBitmap(target); device_context_->SetTarget(target.Get());
} }
} }
return hr; return hr;
@ -384,15 +381,6 @@ HRESULT D2DDeviceResources::HandleDeviceLost(_In_ ComPtr<IDXGIDevice> dxgi_devic
return hr; return hr;
} }
void D2DDeviceResources::SetTargetBitmap(ComPtr<ID2D1Bitmap1> target)
{
target_bitmap_ = target;
if (device_context_)
{
device_context_->SetTarget(target_bitmap_.Get());
}
}
void D2DDeviceResources::ResetTextRenderingParams(HMONITOR monitor) void D2DDeviceResources::ResetTextRenderingParams(HMONITOR monitor)
{ {
if (!dwrite_factory_ || device_context_) if (!dwrite_factory_ || device_context_)

View File

@ -78,8 +78,6 @@ public:
virtual void DiscardResources() = 0; virtual void DiscardResources() = 0;
virtual void SetTargetBitmap(_In_ ComPtr<ID2D1Bitmap1> target) = 0;
virtual void ResetTextRenderingParams(_In_ HMONITOR monitor) = 0; virtual void ResetTextRenderingParams(_In_ HMONITOR monitor) = 0;
inline ID2D1Factory1* GetFactory() inline ID2D1Factory1* GetFactory()
@ -112,17 +110,10 @@ public:
return device_context_.Get(); return device_context_.Get();
} }
inline ID2D1Bitmap1* GetTargetBitmap()
{
KGE_ASSERT(target_bitmap_);
return target_bitmap_.Get();
}
protected: protected:
ComPtr<ID2D1Factory1> factory_; ComPtr<ID2D1Factory1> factory_;
ComPtr<ID2D1Device> device_; ComPtr<ID2D1Device> device_;
ComPtr<ID2D1DeviceContext> device_context_; ComPtr<ID2D1DeviceContext> device_context_;
ComPtr<ID2D1Bitmap1> target_bitmap_;
ComPtr<IWICImagingFactory> imaging_factory_; ComPtr<IWICImagingFactory> imaging_factory_;
ComPtr<IDWriteFactory> dwrite_factory_; ComPtr<IDWriteFactory> dwrite_factory_;

View File

@ -22,6 +22,10 @@
namespace kiwano namespace kiwano
{ {
namespace graphics
{
namespace directx
{
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
// //
// FontCollectionLoader // FontCollectionLoader
@ -41,7 +45,7 @@ public:
// IDWriteFontCollectionLoader methods // IDWriteFontCollectionLoader methods
virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(IDWriteFactory* pFactory, void const* collectionKey, virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(IDWriteFactory* pFactory, void const* collectionKey,
uint32_t collectionKeySize, uint32_t collectionKeySize,
_Out_ IDWriteFontFileEnumerator** fontFileEnumerator); _Out_ IDWriteFontFileEnumerator** fontFileEnumerator);
// IUnknown methods // IUnknown methods
@ -348,7 +352,7 @@ public:
// IDWriteFontCollectionLoader methods // IDWriteFontCollectionLoader methods
virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(IDWriteFactory* pFactory, void const* collectionKey, virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(IDWriteFactory* pFactory, void const* collectionKey,
uint32_t collectionKeySize, uint32_t collectionKeySize,
_Out_ IDWriteFontFileEnumerator** fontFileEnumerator); _Out_ IDWriteFontFileEnumerator** fontFileEnumerator);
// IUnknown methods // IUnknown methods
@ -389,8 +393,7 @@ HRESULT IResourceFontCollectionLoader::Create(_Out_ IResourceFontCollectionLoade
return hr; return hr;
} }
STDMETHODIMP ResourceFontCollectionLoader::AddResources(const Vector<BinaryData>& data, STDMETHODIMP ResourceFontCollectionLoader::AddResources(const Vector<BinaryData>& data, _Out_ LPVOID* pCollectionKey,
_Out_ LPVOID* pCollectionKey,
_Out_ uint32_t* pCollectionKeySize) _Out_ uint32_t* pCollectionKeySize)
{ {
if (!pCollectionKey || !pCollectionKeySize) if (!pCollectionKey || !pCollectionKeySize)
@ -492,8 +495,8 @@ public:
} }
// IDWriteFontFileLoader methods // IDWriteFontFileLoader methods
virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey, virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const* fontFileReferenceKey,
uint32_t fontFileReferenceKeySize, uint32_t fontFileReferenceKeySize,
_Out_ IDWriteFontFileStream** fontFileStream); _Out_ IDWriteFontFileStream** fontFileStream);
// IUnknown methods // IUnknown methods
@ -891,4 +894,6 @@ ULONG STDMETHODCALLTYPE ResourceFontFileStream::Release()
return newCount; return newCount;
} }
} // namespace directx
} // namespace graphics
} // namespace kiwano } // namespace kiwano

View File

@ -25,6 +25,10 @@
namespace kiwano namespace kiwano
{ {
namespace graphics
{
namespace directx
{
interface DWRITE_DECLARE_INTERFACE("7EC7A55A-1964-4098-83E0-EFA7C12C6EF7") IFontCollectionLoader interface DWRITE_DECLARE_INTERFACE("7EC7A55A-1964-4098-83E0-EFA7C12C6EF7") IFontCollectionLoader
: public IDWriteFontCollectionLoader : public IDWriteFontCollectionLoader
{ {
@ -78,4 +82,6 @@ public:
static HRESULT Create(_Out_ IResourceFontFileStream** ppStream, const BinaryData& data); static HRESULT Create(_Out_ IResourceFontFileStream** ppStream, const BinaryData& data);
}; };
} // namespace directx
} // namespace graphics
} // namespace kiwano } // namespace kiwano

View File

@ -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 <kiwano/render/NativeObject.h>
#include <kiwano/platform/win32/ComPtr.hpp>
#include <unknwn.h>
namespace kiwano
{
class KGE_API NativePtr
{
public:
template <typename _Ty, typename = typename std::enable_if<std::is_base_of<IUnknown, _Ty>::value, int>::type>
static inline ComPtr<_Ty> Get(const NativeObject* object)
{
if (object)
{
ComPtr<IUnknown> ptr = object->GetNativePointer<IUnknown>();
if (ptr)
{
ComPtr<_Ty> native;
if (SUCCEEDED(ptr->QueryInterface<_Ty>(&native)))
return native;
}
}
return nullptr;
}
template <typename _Ty>
static inline ComPtr<_Ty> Get(const NativeObject& object)
{
return NativePtr::Get<_Ty>(&object);
}
template <typename _Ty>
static inline ComPtr<_Ty> Get(NativeObjectPtr object)
{
return NativePtr::Get<_Ty>(object.Get());
}
static inline void Set(NativeObject* object, ComPtr<IUnknown> com_ptr)
{
if (object)
{
object->ResetNativePointer(com_ptr.Get());
}
}
static inline void Set(NativeObject& object, ComPtr<IUnknown> com_ptr)
{
NativePtr::Set(&object, com_ptr);
}
static inline void Set(NativeObjectPtr object, ComPtr<IUnknown> com_ptr)
{
NativePtr::Set(object.Get(), com_ptr);
}
};
} // namespace kiwano

View File

@ -19,13 +19,15 @@
// THE SOFTWARE. // THE SOFTWARE.
#include <kiwano/render/DirectX/RenderContextImpl.h> #include <kiwano/render/DirectX/RenderContextImpl.h>
#include <kiwano/render/DirectX/NativePtr.h>
#include <kiwano/render/Renderer.h> #include <kiwano/render/Renderer.h>
#include <kiwano/utils/Logger.h> #include <kiwano/utils/Logger.h>
namespace kiwano namespace kiwano
{ {
namespace graphics
{
namespace directx
{
RenderContextImpl::RenderContextImpl() {} RenderContextImpl::RenderContextImpl() {}
RenderContextImpl::~RenderContextImpl() RenderContextImpl::~RenderContextImpl()
@ -33,23 +35,23 @@ RenderContextImpl::~RenderContextImpl()
DiscardDeviceResources(); DiscardDeviceResources();
} }
HRESULT RenderContextImpl::CreateDeviceResources(ComPtr<ID2D1Factory> factory, ComPtr<ID2D1RenderTarget> render_target) HRESULT RenderContextImpl::CreateDeviceResources(ComPtr<ID2D1Factory> factory, ComPtr<ID2D1DeviceContext> ctx)
{ {
if (!factory || !render_target) if (!factory || !ctx)
return E_INVALIDARG; return E_INVALIDARG;
render_target_ = render_target; render_ctx_ = ctx;
text_renderer_.Reset(); text_renderer_.Reset();
current_brush_.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)) if (SUCCEEDED(hr))
{ {
SetAntialiasMode(antialias_); SetAntialiasMode(antialias_);
SetTextAntialiasMode(text_antialias_); SetTextAntialiasMode(text_antialias_);
Resize(reinterpret_cast<const Size&>(render_target->GetSize())); Resize(reinterpret_cast<const Size&>(render_ctx_->GetSize()));
} }
// DrawingStateBlock // DrawingStateBlock
@ -60,7 +62,7 @@ HRESULT RenderContextImpl::CreateDeviceResources(ComPtr<ID2D1Factory> factory, C
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
NativePtr::Set(this, render_target); NativeObject::Set(this, ctx);
} }
return hr; return hr;
} }
@ -68,28 +70,42 @@ HRESULT RenderContextImpl::CreateDeviceResources(ComPtr<ID2D1Factory> factory, C
void RenderContextImpl::DiscardDeviceResources() void RenderContextImpl::DiscardDeviceResources()
{ {
text_renderer_.Reset(); text_renderer_.Reset();
render_target_.Reset(); render_ctx_.Reset();
current_brush_.Reset(); current_brush_.Reset();
ResetNativePointer(); ResetNativePointer();
} }
TexturePtr RenderContextImpl::GetTarget() const
{
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
ComPtr<ID2D1Image> target;
render_ctx_->GetTarget(&target);
if (target)
{
TexturePtr ptr = MakePtr<Texture>();
NativeObject::Set(*ptr, target.Get());
}
return nullptr;
}
void RenderContextImpl::BeginDraw() void RenderContextImpl::BeginDraw()
{ {
KGE_ASSERT(render_target_ && "Render target has not been initialized!"); KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
SaveDrawingState(); SaveDrawingState();
RenderContext::BeginDraw(); RenderContext::BeginDraw();
render_target_->BeginDraw(); render_ctx_->BeginDraw();
} }
void RenderContextImpl::EndDraw() 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"); KGE_THROW_IF_FAILED(hr, "ID2D1RenderTarget EndDraw failed");
RenderContext::EndDraw(); RenderContext::EndDraw();
@ -97,9 +113,25 @@ void RenderContextImpl::EndDraw()
RestoreDrawingState(); RestoreDrawingState();
} }
void RenderContextImpl::CreateTexture(Texture& texture, const PixelSize& size)
{
KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
ComPtr<ID2D1Bitmap> 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) 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()) if (texture.IsValid())
{ {
@ -113,8 +145,8 @@ void RenderContextImpl::DrawTexture(const Texture& texture, const Rect* src_rect
mode = D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR; mode = D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
} }
auto bitmap = NativePtr::Get<ID2D1Bitmap>(texture); auto bitmap = NativeObject::Get<ID2D1Bitmap>(texture);
render_target_->DrawBitmap(bitmap.Get(), dest_rect ? &DX::ConvertToRectF(*dest_rect) : nullptr, brush_opacity_, render_ctx_->DrawBitmap(bitmap.Get(), dest_rect ? &DX::ConvertToRectF(*dest_rect) : nullptr, brush_opacity_,
mode, src_rect ? &DX::ConvertToRectF(*src_rect) : nullptr); mode, src_rect ? &DX::ConvertToRectF(*src_rect) : nullptr);
IncreasePrimitivesCount(); IncreasePrimitivesCount();
@ -127,10 +159,10 @@ void RenderContextImpl::DrawTextLayout(const TextLayout& layout, const Point& of
if (layout.IsValid()) if (layout.IsValid())
{ {
auto native = NativePtr::Get<IDWriteTextLayout>(layout); auto native = NativeObject::Get<IDWriteTextLayout>(layout);
auto fill_brush = NativePtr::Get<ID2D1Brush>(current_brush_); auto fill_brush = NativeObject::Get<ID2D1Brush>(current_brush_);
auto outline_brush = NativePtr::Get<ID2D1Brush>(current_outline_brush); auto outline_brush = NativeObject::Get<ID2D1Brush>(current_outline_brush);
auto outline_stroke = NativePtr::Get<ID2D1StrokeStyle>(current_stroke_); auto outline_stroke = NativeObject::Get<ID2D1StrokeStyle>(current_stroke_);
float outline_width = 1.0f; float outline_width = 1.0f;
if (fill_brush) if (fill_brush)
@ -164,17 +196,17 @@ void RenderContextImpl::DrawTextLayout(const TextLayout& layout, const Point& of
void RenderContextImpl::DrawShape(const Shape& shape) 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!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
if (shape.IsValid()) if (shape.IsValid())
{ {
auto geometry = NativePtr::Get<ID2D1Geometry>(shape); auto geometry = NativeObject::Get<ID2D1Geometry>(shape);
auto brush = NativePtr::Get<ID2D1Brush>(current_brush_); auto brush = NativeObject::Get<ID2D1Brush>(current_brush_);
auto stroke_style = NativePtr::Get<ID2D1StrokeStyle>(current_stroke_); auto stroke_style = NativeObject::Get<ID2D1StrokeStyle>(current_stroke_);
float stroke_width = current_stroke_ ? current_stroke_->GetWidth() : 1.0f; 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(); IncreasePrimitivesCount();
} }
@ -182,14 +214,14 @@ void RenderContextImpl::DrawShape(const Shape& shape)
void RenderContextImpl::DrawLine(const Point& point1, const Point& point2) 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!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
auto brush = NativePtr::Get<ID2D1Brush>(current_brush_); auto brush = NativeObject::Get<ID2D1Brush>(current_brush_);
auto stroke_style = NativePtr::Get<ID2D1StrokeStyle>(current_stroke_); auto stroke_style = NativeObject::Get<ID2D1StrokeStyle>(current_stroke_);
float stroke_width = current_stroke_ ? current_stroke_->GetWidth() : 1.0f; 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()); stroke_style.Get());
IncreasePrimitivesCount(); IncreasePrimitivesCount();
@ -197,28 +229,28 @@ void RenderContextImpl::DrawLine(const Point& point1, const Point& point2)
void RenderContextImpl::DrawRectangle(const Rect& rect) 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!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
auto brush = NativePtr::Get<ID2D1Brush>(current_brush_); auto brush = NativeObject::Get<ID2D1Brush>(current_brush_);
auto stroke_style = NativePtr::Get<ID2D1StrokeStyle>(current_stroke_); auto stroke_style = NativeObject::Get<ID2D1StrokeStyle>(current_stroke_);
float stroke_width = current_stroke_ ? current_stroke_->GetWidth() : 1.0f; 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(); IncreasePrimitivesCount();
} }
void RenderContextImpl::DrawRoundedRectangle(const Rect& rect, const Vec2& radius) 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!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
auto brush = NativePtr::Get<ID2D1Brush>(current_brush_); auto brush = NativeObject::Get<ID2D1Brush>(current_brush_);
auto stroke_style = NativePtr::Get<ID2D1StrokeStyle>(current_stroke_); auto stroke_style = NativeObject::Get<ID2D1StrokeStyle>(current_stroke_);
float stroke_width = current_stroke_ ? current_stroke_->GetWidth() : 1.0f; 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()); stroke_width, stroke_style.Get());
IncreasePrimitivesCount(); IncreasePrimitivesCount();
@ -226,14 +258,14 @@ void RenderContextImpl::DrawRoundedRectangle(const Rect& rect, const Vec2& radiu
void RenderContextImpl::DrawEllipse(const Point& center, const Vec2& radius) 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!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
auto brush = NativePtr::Get<ID2D1Brush>(current_brush_); auto brush = NativeObject::Get<ID2D1Brush>(current_brush_);
auto stroke_style = NativePtr::Get<ID2D1StrokeStyle>(current_stroke_); auto stroke_style = NativeObject::Get<ID2D1StrokeStyle>(current_stroke_);
float stroke_width = current_stroke_ ? current_stroke_->GetWidth() : 1.0f; 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()); stroke_width, stroke_style.Get());
IncreasePrimitivesCount(); IncreasePrimitivesCount();
@ -241,14 +273,14 @@ void RenderContextImpl::DrawEllipse(const Point& center, const Vec2& radius)
void RenderContextImpl::FillShape(const Shape& shape) 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!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
if (shape.IsValid()) if (shape.IsValid())
{ {
auto brush = NativePtr::Get<ID2D1Brush>(current_brush_); auto brush = NativeObject::Get<ID2D1Brush>(current_brush_);
auto geometry = NativePtr::Get<ID2D1Geometry>(shape); auto geometry = NativeObject::Get<ID2D1Geometry>(shape);
render_target_->FillGeometry(geometry.Get(), brush.Get()); render_ctx_->FillGeometry(geometry.Get(), brush.Get());
IncreasePrimitivesCount(); IncreasePrimitivesCount();
} }
@ -256,56 +288,40 @@ void RenderContextImpl::FillShape(const Shape& shape)
void RenderContextImpl::FillRectangle(const Rect& rect) 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!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
auto brush = NativePtr::Get<ID2D1Brush>(current_brush_); auto brush = NativeObject::Get<ID2D1Brush>(current_brush_);
render_target_->FillRectangle(DX::ConvertToRectF(rect), brush.Get()); render_ctx_->FillRectangle(DX::ConvertToRectF(rect), brush.Get());
IncreasePrimitivesCount(); IncreasePrimitivesCount();
} }
void RenderContextImpl::FillRoundedRectangle(const Rect& rect, const Vec2& radius) 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!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
auto brush = NativePtr::Get<ID2D1Brush>(current_brush_); auto brush = NativeObject::Get<ID2D1Brush>(current_brush_);
render_target_->FillRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y), brush.Get()); render_ctx_->FillRoundedRectangle(D2D1::RoundedRect(DX::ConvertToRectF(rect), radius.x, radius.y), brush.Get());
IncreasePrimitivesCount(); IncreasePrimitivesCount();
} }
void RenderContextImpl::FillEllipse(const Point& center, const Vec2& radius) 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!"); KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
auto brush = NativePtr::Get<ID2D1Brush>(current_brush_); auto brush = NativeObject::Get<ID2D1Brush>(current_brush_);
render_target_->FillEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y), brush.Get()); render_ctx_->FillEllipse(D2D1::Ellipse(DX::ConvertToPoint2F(center), radius.x, radius.y), brush.Get());
IncreasePrimitivesCount(); IncreasePrimitivesCount();
} }
void RenderContextImpl::CreateTexture(Texture& texture, math::Vec2T<uint32_t> size)
{
KGE_ASSERT(render_target_ && "Render target has not been initialized!");
ComPtr<ID2D1Bitmap> 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) 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; D2D1_ANTIALIAS_MODE mode;
if (antialias_) if (antialias_)
@ -316,29 +332,29 @@ void RenderContextImpl::PushClipRect(const Rect& clip_rect)
{ {
mode = D2D1_ANTIALIAS_MODE_ALIASED; mode = D2D1_ANTIALIAS_MODE_ALIASED;
} }
render_target_->PushAxisAlignedClip(DX::ConvertToRectF(clip_rect), mode); render_ctx_->PushAxisAlignedClip(DX::ConvertToRectF(clip_rect), mode);
} }
void RenderContextImpl::PopClipRect() void RenderContextImpl::PopClipRect()
{ {
KGE_ASSERT(render_target_ && "Render target has not been initialized!"); KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
render_target_->PopAxisAlignedClip(); render_ctx_->PopAxisAlignedClip();
} }
void RenderContextImpl::PushLayer(Layer& layer) 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<ID2D1Layer>(layer); auto native = NativeObject::Get<ID2D1Layer>(layer);
auto mask = NativePtr::Get<ID2D1Geometry>(layer.GetMaskShape()); auto mask = NativeObject::Get<ID2D1Geometry>(layer.GetMaskShape());
if (!native) if (!native)
{ {
HRESULT hr = render_target_->CreateLayer(&native); HRESULT hr = render_ctx_->CreateLayer(&native);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
NativePtr::Set(layer, native); NativeObject::Set(layer, native);
} }
KGE_THROW_IF_FAILED(hr, "Create ID2D1Layer failed"); KGE_THROW_IF_FAILED(hr, "Create ID2D1Layer failed");
} }
@ -348,32 +364,32 @@ void RenderContextImpl::PushLayer(Layer& layer)
DX::ConvertToMatrix3x2F(layer.GetMaskTransform()), layer.GetOpacity(), nullptr, DX::ConvertToMatrix3x2F(layer.GetMaskTransform()), layer.GetOpacity(), nullptr,
D2D1_LAYER_OPTIONS_NONE); D2D1_LAYER_OPTIONS_NONE);
render_target_->PushLayer(params, native.Get()); render_ctx_->PushLayer(params, native.Get());
} }
void RenderContextImpl::PopLayer() void RenderContextImpl::PopLayer()
{ {
KGE_ASSERT(render_target_ && "Render target has not been initialized!"); KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
render_target_->PopLayer(); render_ctx_->PopLayer();
} }
void RenderContextImpl::Clear() void RenderContextImpl::Clear()
{ {
KGE_ASSERT(render_target_ && "Render target has not been initialized!"); KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
render_target_->Clear(); render_ctx_->Clear();
} }
void RenderContextImpl::Clear(const Color& clear_color) void RenderContextImpl::Clear(const Color& clear_color)
{ {
KGE_ASSERT(render_target_ && "Render target has not been initialized!"); KGE_ASSERT(render_ctx_ && "Render target has not been initialized!");
render_target_->Clear(DX::ConvertToColorF(clear_color)); render_ctx_->Clear(DX::ConvertToColorF(clear_color));
} }
Size RenderContextImpl::GetSize() const Size RenderContextImpl::GetSize() const
{ {
if (render_target_) if (render_ctx_)
{ {
return reinterpret_cast<const Size&>(render_target_->GetSize()); return reinterpret_cast<const Size&>(render_ctx_->GetSize());
} }
return Size(); return Size();
} }
@ -384,7 +400,7 @@ void RenderContextImpl::SetCurrentBrush(BrushPtr brush)
if (current_brush_ && current_brush_->IsValid()) if (current_brush_ && current_brush_->IsValid())
{ {
NativePtr::Get<ID2D1Brush>(current_brush_)->SetOpacity(brush_opacity_); NativeObject::Get<ID2D1Brush>(current_brush_)->SetOpacity(brush_opacity_);
} }
} }
@ -400,30 +416,30 @@ void RenderContextImpl::SetCurrentStrokeStyle(StrokeStylePtr stroke_style)
void RenderContextImpl::SetTransform(const Matrix3x2& matrix) 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_) if (fast_global_transform_)
{ {
render_target_->SetTransform(DX::ConvertToMatrix3x2F(&matrix)); render_ctx_->SetTransform(DX::ConvertToMatrix3x2F(&matrix));
} }
else else
{ {
Matrix3x2 result = matrix * global_transform_; Matrix3x2 result = matrix * global_transform_;
render_target_->SetTransform(DX::ConvertToMatrix3x2F(&result)); render_ctx_->SetTransform(DX::ConvertToMatrix3x2F(&result));
} }
} }
void RenderContextImpl::SetAntialiasMode(bool enabled) 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; antialias_ = enabled;
} }
void RenderContextImpl::SetTextAntialiasMode(TextAntialiasMode mode) 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; D2D1_TEXT_ANTIALIAS_MODE antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
switch (mode) switch (mode)
@ -445,12 +461,12 @@ void RenderContextImpl::SetTextAntialiasMode(TextAntialiasMode mode)
} }
text_antialias_ = mode; text_antialias_ = mode;
render_target_->SetTextAntialiasMode(antialias_mode); render_ctx_->SetTextAntialiasMode(antialias_mode);
} }
bool RenderContextImpl::CheckVisibility(const Rect& bounds, const Matrix3x2& transform) 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_) if (fast_global_transform_)
{ {
@ -470,7 +486,7 @@ void RenderContextImpl::SaveDrawingState()
if (drawing_state_) 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_) if (drawing_state_)
{ {
render_target_->RestoreDrawingState(drawing_state_.Get()); render_ctx_->RestoreDrawingState(drawing_state_.Get());
} }
} }
} // namespace directx
} // namespace graphics
} // namespace kiwano } // namespace kiwano

View File

@ -24,7 +24,10 @@
namespace kiwano namespace kiwano
{ {
namespace graphics
{
namespace directx
{
KGE_DECLARE_SMART_PTR(RenderContextImpl); KGE_DECLARE_SMART_PTR(RenderContextImpl);
class KGE_API RenderContextImpl : public RenderContext class KGE_API RenderContextImpl : public RenderContext
@ -34,12 +37,14 @@ public:
virtual ~RenderContextImpl(); virtual ~RenderContextImpl();
HRESULT CreateDeviceResources(ComPtr<ID2D1Factory> factory, ComPtr<ID2D1RenderTarget> render_target); HRESULT CreateDeviceResources(ComPtr<ID2D1Factory> factory, ComPtr<ID2D1DeviceContext> ctx);
void BeginDraw() override; void BeginDraw() override;
void EndDraw() 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 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; 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 FillEllipse(const Point& center, const Vec2& radius) override;
void CreateTexture(Texture& texture, math::Vec2T<uint32_t> size) override;
void PushClipRect(const Rect& clip_rect) override; void PushClipRect(const Rect& clip_rect) override;
void PopClipRect() override; void PopClipRect() override;
@ -92,6 +95,8 @@ public:
void Resize(const Size& size) override; void Resize(const Size& size) override;
TexturePtr GetTarget() const override;
private: private:
void DiscardDeviceResources(); void DiscardDeviceResources();
@ -101,8 +106,10 @@ private:
private: private:
ComPtr<ITextRenderer> text_renderer_; ComPtr<ITextRenderer> text_renderer_;
ComPtr<ID2D1RenderTarget> render_target_; ComPtr<ID2D1DeviceContext> render_ctx_;
ComPtr<ID2D1DrawingStateBlock> drawing_state_; ComPtr<ID2D1DrawingStateBlock> drawing_state_;
}; };
} // namespace directx
} // namespace graphics
} // namespace kiwano } // namespace kiwano

View File

@ -20,11 +20,11 @@
#include <kiwano/utils/Logger.h> #include <kiwano/utils/Logger.h>
#include <kiwano/event/Events.h> #include <kiwano/event/Events.h>
#include <kiwano/render/NativeObject.h>
#include <kiwano/platform/FileSystem.h> #include <kiwano/platform/FileSystem.h>
#include <kiwano/platform/Application.h> #include <kiwano/platform/Application.h>
#include <kiwano/render/ShapeMaker.h> #include <kiwano/render/ShapeMaker.h>
#include <kiwano/render/DirectX/RendererImpl.h> #include <kiwano/render/DirectX/RendererImpl.h>
#include <kiwano/render/DirectX/NativePtr.h>
#define KGE_SET_STATUS_IF_FAILED(ERRCODE, OBJ, MESSAGE) \ #define KGE_SET_STATUS_IF_FAILED(ERRCODE, OBJ, MESSAGE) \
if (FAILED(ERRCODE)) \ if (FAILED(ERRCODE)) \
@ -37,24 +37,24 @@ namespace kiwano
using namespace kiwano::graphics::directx; using namespace kiwano::graphics::directx;
inline const GUID& ConvertPixelFormat(PixelFormat format, UINT& stride) inline DXGI_FORMAT ConvertPixelFormat(PixelFormat format, UINT32& pitch)
{ {
switch (format) switch (format)
{ {
case PixelFormat::Bpp32RGB: //case PixelFormat::Bpp32RGB:
stride = 3; // pitch = 4;
return GUID_WICPixelFormat32bppRGB; // return DXGI_FORMAT_R8G8B8X8_UNORM;
case PixelFormat::Bpp32RGBA: case PixelFormat::Bpp32RGBA:
stride = 4; pitch = 4;
return GUID_WICPixelFormat32bppRGBA; return DXGI_FORMAT_R8G8B8A8_UNORM;
case PixelFormat::Bpp32BGR: case PixelFormat::Bpp32BGR:
stride = 3; pitch = 4;
return GUID_WICPixelFormat32bppBGR; return DXGI_FORMAT_B8G8R8X8_UNORM;
case PixelFormat::Bpp32BGRA: case PixelFormat::Bpp32BGRA:
stride = 4; pitch = 4;
return GUID_WICPixelFormat32bppBGRA; return DXGI_FORMAT_B8G8R8A8_UNORM;
default: default:
return GUID_WICPixelFormatDontCare; return DXGI_FORMAT_UNKNOWN;
} }
} }
@ -258,7 +258,7 @@ void RendererImpl::CreateTexture(Texture& texture, const String& file_path)
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
NativePtr::Set(texture, bitmap); NativeObject::Set(texture, bitmap);
texture.SetSize({ bitmap->GetSize().width, bitmap->GetSize().height }); texture.SetSize({ bitmap->GetSize().width, bitmap->GetSize().height });
texture.SetSizeInPixels({ bitmap->GetPixelSize().width, bitmap->GetPixelSize().height }); texture.SetSizeInPixels({ bitmap->GetPixelSize().width, bitmap->GetPixelSize().height });
@ -307,7 +307,7 @@ void RendererImpl::CreateTexture(Texture& texture, const BinaryData& data)
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
NativePtr::Set(texture, bitmap); NativeObject::Set(texture, bitmap);
texture.SetSize({ bitmap->GetSize().width, bitmap->GetSize().height }); texture.SetSize({ bitmap->GetSize().width, bitmap->GetSize().height });
texture.SetSizeInPixels({ bitmap->GetPixelSize().width, bitmap->GetPixelSize().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)) if (SUCCEEDED(hr))
{ {
UINT stride = 0; ComPtr<ID2D1Bitmap1> output;
const auto& wicFormat = ConvertPixelFormat(format, stride); UINT32 pitch = 0;
const auto dxgi_format = ConvertPixelFormat(format, pitch);
ComPtr<IWICBitmapSource> source;
hr = d2d_res_->CreateBitmapSourceFromMemory(source, UINT(size.x), UINT(size.y), UINT(size.x) * stride,
UINT(data.size), reinterpret_cast<BYTE*>(data.buffer),
wicFormat);
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)) if (SUCCEEDED(hr))
{ {
ComPtr<IWICFormatConverter> converter; NativeObject::Set(texture, output);
hr = d2d_res_->CreateBitmapConverter(converter, source, GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone, nullptr, 0.f,
WICBitmapPaletteTypeMedianCut);
if (SUCCEEDED(hr)) texture.SetSize({ output->GetSize().width, output->GetSize().height });
{ texture.SetSizeInPixels({ output->GetPixelSize().width, output->GetPixelSize().height });
ComPtr<ID2D1Bitmap> 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 });
}
}
} }
} }
} }
@ -395,7 +380,7 @@ void RendererImpl::CreateGifImage(GifImage& gif, const String& file_path)
if (SUCCEEDED(hr)) 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)) 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; hr = E_UNEXPECTED;
} }
auto decoder = NativePtr::Get<IWICBitmapDecoder>(gif); auto decoder = NativeObject::Get<IWICBitmapDecoder>(gif);
if (!decoder) if (!decoder)
{ {
@ -464,7 +449,7 @@ void RendererImpl::CreateGifImageFrame(GifImage::Frame& frame, const GifImage& g
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
frame.texture = MakePtr<Texture>(); frame.texture = MakePtr<Texture>();
NativePtr::Set(frame.texture, bitmap); NativeObject::Set(frame.texture, bitmap);
frame.texture->SetSize({ bitmap->GetSize().width, bitmap->GetSize().height }); frame.texture->SetSize({ bitmap->GetSize().width, bitmap->GetSize().height });
frame.texture->SetSizeInPixels({ bitmap->GetPixelSize().width, bitmap->GetPixelSize().height }); frame.texture->SetSizeInPixels({ bitmap->GetPixelSize().width, bitmap->GetPixelSize().height });
@ -618,7 +603,7 @@ void RendererImpl::CreateFontCollection(Font& font, Vector<String>& family_names
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
d2d_res_->GetFontFamilyNames(family_names, font_collection); // ignore the result 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<String>& family_names
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
d2d_res_->GetFontFamilyNames(family_names, font_collection); // ignore the result 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_weight = DWRITE_FONT_WEIGHT(font->GetWeight());
auto font_style = DWRITE_FONT_STYLE(font->GetPosture()); auto font_style = DWRITE_FONT_STYLE(font->GetPosture());
auto font_stretch = DWRITE_FONT_STRETCH(font->GetStretch()); auto font_stretch = DWRITE_FONT_STRETCH(font->GetStretch());
auto collection = NativePtr::Get<IDWriteFontCollection>(font); auto collection = NativeObject::Get<IDWriteFontCollection>(font);
WideString font_family; WideString font_family;
@ -698,7 +683,7 @@ void RendererImpl::CreateTextLayout(TextLayout& layout, const String& content, c
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
NativePtr::Set(layout, output); NativeObject::Set(layout, output);
layout.SetDirtyFlag(TextLayout::DirtyFlag::Dirty); layout.SetDirtyFlag(TextLayout::DirtyFlag::Dirty);
} }
} }
@ -735,7 +720,7 @@ void RendererImpl::CreateLineShape(Shape& shape, const Point& begin_pos, const P
if (SUCCEEDED(hr)) 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)) if (SUCCEEDED(hr))
{ {
NativePtr::Set(shape, output); NativeObject::Set(shape, output);
} }
KGE_SET_STATUS_IF_FAILED(hr, shape, "Create ID2D1RectangleGeometry failed"); 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)) if (SUCCEEDED(hr))
{ {
NativePtr::Set(shape, output); NativeObject::Set(shape, output);
} }
KGE_SET_STATUS_IF_FAILED(hr, shape, "Create ID2D1RoundedRectangleGeometry failed"); 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)) if (SUCCEEDED(hr))
{ {
NativePtr::Set(shape, output); NativeObject::Set(shape, output);
} }
KGE_SET_STATUS_IF_FAILED(hr, shape, "Create ID2D1EllipseGeometry failed"); KGE_SET_STATUS_IF_FAILED(hr, shape, "Create ID2D1EllipseGeometry failed");
@ -828,7 +813,7 @@ void RendererImpl::CreateShapeSink(ShapeMaker& maker)
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
ShapePtr shape = MakePtr<Shape>(); ShapePtr shape = MakePtr<Shape>();
NativePtr::Set(shape, geometry); NativeObject::Set(shape, geometry);
maker.SetShape(shape); maker.SetShape(shape);
} }
@ -850,7 +835,7 @@ void RendererImpl::CreateBrush(Brush& brush, const Color& color)
if (brush.GetType() == Brush::Type::SolidColor && brush.IsValid()) if (brush.GetType() == Brush::Type::SolidColor && brush.IsValid())
{ {
hr = NativePtr::Get<ID2D1Brush>(brush)->QueryInterface(&solid_brush); hr = NativeObject::Get<ID2D1Brush>(brush)->QueryInterface(&solid_brush);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
solid_brush->SetColor(DX::ConvertToColorF(color)); solid_brush->SetColor(DX::ConvertToColorF(color));
@ -862,7 +847,7 @@ void RendererImpl::CreateBrush(Brush& brush, const Color& color)
if (SUCCEEDED(hr)) 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)) 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)) 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)) if (SUCCEEDED(hr))
{ {
auto bitmap = NativePtr::Get<ID2D1Bitmap>(texture); auto bitmap = NativeObject::Get<ID2D1Bitmap>(texture);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -954,7 +939,7 @@ void RendererImpl::CreateBrush(Brush& brush, TexturePtr texture)
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
NativePtr::Set(brush, output); NativeObject::Set(brush, output);
} }
} }
} }
@ -994,55 +979,60 @@ void RendererImpl::CreateStrokeStyle(StrokeStyle& stroke_style)
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
NativePtr::Set(stroke_style, output); NativeObject::Set(stroke_style, output);
} }
} }
KGE_SET_STATUS_IF_FAILED(hr, stroke_style, "Create ID2D1StrokeStyle failed"); 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<RenderContextImpl>();
HRESULT hr = S_OK; HRESULT hr = S_OK;
if (!d2d_res_) if (!d2d_res_)
{ {
hr = E_UNEXPECTED; hr = E_UNEXPECTED;
} }
else if (texture == nullptr)
{
hr = E_INVALIDARG;
}
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
ComPtr<ID2D1BitmapRenderTarget> bitmap_rt; RenderContextImplPtr ptr = MakePtr<RenderContextImpl>();
if (desired_size) ComPtr<ID2D1DeviceContext> 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), hr = ptr->CreateDeviceResources(d2d_res_->GetFactory(), render_ctx);
&bitmap_rt);
}
else
{
hr = d2d_res_->GetDeviceContext()->CreateCompatibleRenderTarget(&bitmap_rt);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = ptr->CreateDeviceResources(d2d_res_->GetFactory(), bitmap_rt); ComPtr<ID2D1Bitmap1> 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<ID2D1Bitmap> output;
hr = bitmap_rt->GetBitmap(&output);
if (SUCCEEDED(hr)) 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)) KGE_THROW_IF_FAILED(hr, "Create render context failed");
return ptr;
return nullptr; return nullptr;
} }
@ -1056,7 +1046,7 @@ void RendererImpl::Resize(uint32_t width, uint32_t height)
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
// Clear resources // Clear resources
d2d_res_->SetTargetBitmap(nullptr); d2d_res_->GetDeviceContext()->SetTarget(nullptr);
} }
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))

View File

@ -36,7 +36,7 @@ public:
void CreateTexture(Texture& texture, const BinaryData& data) override; 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; void CreateGifImage(GifImage& gif, const String& file_path) override;
@ -70,7 +70,7 @@ public:
void CreateStrokeStyle(StrokeStyle& stroke_style) override; 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: public:
void Clear() override; void Clear() override;

View File

@ -23,6 +23,10 @@
namespace kiwano namespace kiwano
{ {
namespace graphics
{
namespace directx
{
class TextDrawingEffect : public ITextDrawingEffect class TextDrawingEffect : public ITextDrawingEffect
{ {
public: public:
@ -39,8 +43,8 @@ public:
virtual ULONG STDMETHODCALLTYPE Release(); virtual ULONG STDMETHODCALLTYPE Release();
private: private:
unsigned long cRefCount_; unsigned long cRefCount_;
ComPtr<ID2D1Factory> pFactory_; ComPtr<ID2D1Factory> pFactory_;
// Outline geometry cache // Outline geometry cache
Map<std::tuple<const DWRITE_GLYPH_RUN*, float, float>, ComPtr<ID2D1Geometry>> outlineCache_; Map<std::tuple<const DWRITE_GLYPH_RUN*, float, float>, ComPtr<ID2D1Geometry>> outlineCache_;
@ -194,4 +198,6 @@ STDMETHODIMP TextDrawingEffect::QueryInterface(REFIID riid, void** ppvObject)
return S_OK; return S_OK;
} }
} // namespace directx
} // namespace graphics
} // namespace kiwano } // namespace kiwano

View File

@ -24,8 +24,12 @@
namespace kiwano namespace kiwano
{ {
namespace graphics
interface DWRITE_DECLARE_INTERFACE("7431F439-6E54-4707-A0DC-1AA035D6AFB8") ITextDrawingEffect : public IUnknown {
namespace directx
{
interface DWRITE_DECLARE_INTERFACE("7431F439-6E54-4707-A0DC-1AA035D6AFB8") ITextDrawingEffect
: public IUnknown
{ {
public: public:
static HRESULT Create(_Out_ ITextDrawingEffect** ppTextDrawingEffect, _In_ ID2D1Factory* pFactory); static HRESULT Create(_Out_ ITextDrawingEffect** ppTextDrawingEffect, _In_ ID2D1Factory* pFactory);
@ -33,4 +37,6 @@ public:
STDMETHOD(CreateOutlineGeomerty) STDMETHOD(CreateOutlineGeomerty)
(_Out_ ID2D1Geometry** ppOutlineGeo, _In_ DWRITE_GLYPH_RUN const* glyphRun, float fOriginX, float fOriginY) PURE; (_Out_ ID2D1Geometry** ppOutlineGeo, _In_ DWRITE_GLYPH_RUN const* glyphRun, float fOriginX, float fOriginY) PURE;
}; };
} // namespace directx
} // namespace graphics
} // namespace kiwano } // namespace kiwano

View File

@ -23,6 +23,10 @@
namespace kiwano namespace kiwano
{ {
namespace graphics
{
namespace directx
{
class TextRenderer : public ITextRenderer class TextRenderer : public ITextRenderer
{ {
public: public:
@ -30,7 +34,7 @@ public:
~TextRenderer(); ~TextRenderer();
STDMETHOD(CreateDeviceResources)(_In_ ID2D1RenderTarget* pRT); STDMETHOD(CreateDeviceResources)(_In_ ID2D1DeviceContext* pContext);
STDMETHOD(DrawTextLayout) STDMETHOD(DrawTextLayout)
(_In_ IDWriteTextLayout* pTextLayout, float fOriginX, float fOriginY, _In_opt_ ID2D1Brush* pDefaultFillBrush, (_In_ IDWriteTextLayout* pTextLayout, float fOriginX, float fOriginY, _In_opt_ ID2D1Brush* pDefaultFillBrush,
@ -67,17 +71,17 @@ public:
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject);
private: private:
unsigned long cRefCount_; unsigned long cRefCount_;
uint32_t cPrimitivesCount_; uint32_t cPrimitivesCount_;
float fDefaultOutlineWidth_; float fDefaultOutlineWidth_;
ComPtr<ID2D1Factory> pFactory_; ComPtr<ID2D1Factory> pFactory_;
ComPtr<ID2D1RenderTarget> pRT_; ComPtr<ID2D1DeviceContext> pContext_;
ComPtr<ID2D1Brush> pDefaultFillBrush_; ComPtr<ID2D1Brush> pDefaultFillBrush_;
ComPtr<ID2D1Brush> pDefaultOutlineBrush_; ComPtr<ID2D1Brush> pDefaultOutlineBrush_;
ComPtr<ID2D1StrokeStyle> pDefaultStrokeStyle_; ComPtr<ID2D1StrokeStyle> pDefaultStrokeStyle_;
}; };
HRESULT ITextRenderer::Create(_Out_ ITextRenderer** ppTextRenderer, _In_ ID2D1RenderTarget* pRT) HRESULT ITextRenderer::Create(_Out_ ITextRenderer** ppTextRenderer, _In_ ID2D1DeviceContext* pContext)
{ {
HRESULT hr = E_FAIL; HRESULT hr = E_FAIL;
@ -86,7 +90,7 @@ HRESULT ITextRenderer::Create(_Out_ ITextRenderer** ppTextRenderer, _In_ ID2D1Re
TextRenderer* pTextRenderer = new (std::nothrow) TextRenderer; TextRenderer* pTextRenderer = new (std::nothrow) TextRenderer;
if (pTextRenderer) if (pTextRenderer)
{ {
hr = pTextRenderer->CreateDeviceResources(pRT); hr = pTextRenderer->CreateDeviceResources(pContext);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
@ -115,17 +119,17 @@ TextRenderer::TextRenderer()
TextRenderer::~TextRenderer() {} TextRenderer::~TextRenderer() {}
STDMETHODIMP TextRenderer::CreateDeviceResources(_In_ ID2D1RenderTarget* pRT) STDMETHODIMP TextRenderer::CreateDeviceResources(_In_ ID2D1DeviceContext* pContext)
{ {
HRESULT hr = E_FAIL; HRESULT hr = E_FAIL;
pFactory_.Reset(); pFactory_.Reset();
pRT_.Reset(); pContext_.Reset();
if (pRT) if (pContext)
{ {
pRT_ = pRT; pContext_ = pContext;
pRT_->GetFactory(&pFactory_); pContext_->GetFactory(&pFactory_);
hr = S_OK; hr = S_OK;
} }
return hr; return hr;
@ -152,7 +156,7 @@ STDMETHODIMP TextRenderer::DrawTextLayout(_In_ IDWriteTextLayout* pTextLayout, f
STDMETHODIMP TextRenderer::DrawGlyphRun(__maybenull void* clientDrawingContext, float baselineOriginX, STDMETHODIMP TextRenderer::DrawGlyphRun(__maybenull void* clientDrawingContext, float baselineOriginX,
float baselineOriginY, DWRITE_MEASURING_MODE measuringMode, 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, __in DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
IUnknown* clientDrawingEffect) IUnknown* clientDrawingEffect)
{ {
@ -176,8 +180,8 @@ STDMETHODIMP TextRenderer::DrawGlyphRun(__maybenull void* clientDrawingContext,
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
pRT_->DrawGeometry(pOutlineGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_, pContext_->DrawGeometry(pOutlineGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_,
pDefaultStrokeStyle_.Get()); pDefaultStrokeStyle_.Get());
++cPrimitivesCount_; ++cPrimitivesCount_;
} }
@ -187,7 +191,8 @@ STDMETHODIMP TextRenderer::DrawGlyphRun(__maybenull void* clientDrawingContext,
{ {
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
pRT_->DrawGlyphRun(D2D1::Point2F(baselineOriginX, baselineOriginY), glyphRun, pDefaultFillBrush_.Get()); pContext_->DrawGlyphRun(D2D1::Point2F(baselineOriginX, baselineOriginY), glyphRun,
pDefaultFillBrush_.Get());
++cPrimitivesCount_; ++cPrimitivesCount_;
} }
@ -236,15 +241,15 @@ STDMETHODIMP TextRenderer::DrawUnderline(__maybenull void* clientDrawingContext,
if (SUCCEEDED(hr) && pDefaultOutlineBrush_) if (SUCCEEDED(hr) && pDefaultOutlineBrush_)
{ {
pRT_->DrawGeometry(pTransformedGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_, pContext_->DrawGeometry(pTransformedGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_,
pDefaultStrokeStyle_.Get()); pDefaultStrokeStyle_.Get());
++cPrimitivesCount_; ++cPrimitivesCount_;
} }
if (SUCCEEDED(hr) && pCurrentFillBrush) if (SUCCEEDED(hr) && pCurrentFillBrush)
{ {
pRT_->FillGeometry(pTransformedGeometry.Get(), pCurrentFillBrush.Get()); pContext_->FillGeometry(pTransformedGeometry.Get(), pCurrentFillBrush.Get());
++cPrimitivesCount_; ++cPrimitivesCount_;
} }
@ -292,15 +297,15 @@ STDMETHODIMP TextRenderer::DrawStrikethrough(__maybenull void* clientDrawingCont
if (SUCCEEDED(hr) && pDefaultOutlineBrush_) if (SUCCEEDED(hr) && pDefaultOutlineBrush_)
{ {
pRT_->DrawGeometry(pTransformedGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_, pContext_->DrawGeometry(pTransformedGeometry.Get(), pDefaultOutlineBrush_.Get(), fDefaultOutlineWidth_,
pDefaultStrokeStyle_.Get()); pDefaultStrokeStyle_.Get());
++cPrimitivesCount_; ++cPrimitivesCount_;
} }
if (SUCCEEDED(hr) && pCurrentFillBrush) if (SUCCEEDED(hr) && pCurrentFillBrush)
{ {
pRT_->FillGeometry(pTransformedGeometry.Get(), pCurrentFillBrush.Get()); pContext_->FillGeometry(pTransformedGeometry.Get(), pCurrentFillBrush.Get());
++cPrimitivesCount_; ++cPrimitivesCount_;
} }
@ -333,7 +338,7 @@ STDMETHODIMP TextRenderer::GetCurrentTransform(__maybenull void* clientDrawingCo
{ {
KGE_NOT_USED(clientDrawingContext); KGE_NOT_USED(clientDrawingContext);
pRT_->GetTransform(reinterpret_cast<D2D1_MATRIX_3X2_F*>(transform)); pContext_->GetTransform(reinterpret_cast<D2D1_MATRIX_3X2_F*>(transform));
return S_OK; return S_OK;
} }
@ -343,7 +348,7 @@ STDMETHODIMP TextRenderer::GetPixelsPerDip(__maybenull void* clientDrawingContex
float x, yUnused; float x, yUnused;
pRT_->GetDpi(&x, &yUnused); pContext_->GetDpi(&x, &yUnused);
*pixelsPerDip = x / 96; *pixelsPerDip = x / 96;
return S_OK; return S_OK;
@ -400,4 +405,6 @@ STDMETHODIMP TextRenderer::QueryInterface(REFIID riid, void** ppvObject)
return S_OK; return S_OK;
} }
} // namespace directx
} // namespace graphics
} // namespace kiwano } // namespace kiwano

View File

@ -23,16 +23,23 @@
namespace kiwano 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: 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) 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_ ID2D1Brush* pDefaultOutlineBrush, float fDefaultOutlineWidth,
_In_opt_ ID2D1StrokeStyle* pDefaultStrokeStyle) PURE; _In_opt_ ID2D1StrokeStyle* pDefaultStrokeStyle) PURE;
STDMETHOD_(uint32_t, GetLastPrimitivesCount)() PURE; STDMETHOD_(uint32_t, GetLastPrimitivesCount)() PURE;
}; };
} // namespace directx
} // namespace graphics
} // namespace kiwano } // namespace kiwano

View File

@ -23,8 +23,7 @@
#include <kiwano/utils/Logger.h> #include <kiwano/utils/Logger.h>
#include <kiwano/render/Color.h> #include <kiwano/render/Color.h>
#include <kiwano/platform/win32/ComPtr.hpp> #include <kiwano/platform/win32/ComPtr.hpp>
#include <d2d1.h> #include <d2d1_3.h>
#include <d2d1_1.h>
namespace kiwano namespace kiwano
{ {
@ -76,7 +75,7 @@ inline D2D1_POINT_2F* ConvertToPoint2F(Vec2* vec2)
} }
// //
// SizeF // Size
// //
inline const D2D1_SIZE_F& ConvertToSizeF(const Vec2& vec2) inline const D2D1_SIZE_F& ConvertToSizeF(const Vec2& vec2)
@ -99,6 +98,26 @@ inline D2D1_SIZE_F* ConvertToSizeF(Vec2* vec2)
return reinterpret_cast<D2D1_SIZE_F*>(vec2); return reinterpret_cast<D2D1_SIZE_F*>(vec2);
} }
inline const D2D1_SIZE_U& ConvertToSizeU(const math::Vec2T<uint32_t>& vec2)
{
return reinterpret_cast<const D2D1_SIZE_U&>(vec2);
}
inline D2D1_SIZE_U& ConvertToSizeU(math::Vec2T<uint32_t>& vec2)
{
return reinterpret_cast<D2D1_SIZE_U&>(vec2);
}
inline const D2D1_SIZE_U* ConvertToSizeU(const math::Vec2T<uint32_t>* vec2)
{
return reinterpret_cast<const D2D1_SIZE_U*>(vec2);
}
inline D2D1_SIZE_U* ConvertToSizeU(math::Vec2T<uint32_t>* vec2)
{
return reinterpret_cast<D2D1_SIZE_U*>(vec2);
}
// //
// RectF // RectF
// //

View File

@ -19,8 +19,8 @@
// THE SOFTWARE. // THE SOFTWARE.
#pragma once #pragma once
#include <kiwano/render/NativeObject.h>
#include <kiwano/core/Resource.h> #include <kiwano/core/Resource.h>
#include <kiwano/render/NativeObject.h>
namespace kiwano namespace kiwano
{ {

View File

@ -116,14 +116,13 @@ GifImage::Frame GifImage::GetFrame(uint32_t index)
} // namespace kiwano } // namespace kiwano
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
#include <kiwano/render/DirectX/NativePtr.h>
namespace kiwano namespace kiwano
{ {
bool GifImage::GetGlobalMetadata() bool GifImage::GetGlobalMetadata()
{ {
ComPtr<IWICBitmapDecoder> decoder = NativePtr::Get<IWICBitmapDecoder>(this); ComPtr<IWICBitmapDecoder> decoder = NativeObject::Get<IWICBitmapDecoder>(this);
HRESULT hr = decoder ? S_OK : E_FAIL; HRESULT hr = decoder ? S_OK : E_FAIL;

View File

@ -17,10 +17,7 @@ void NativeObjectBase::ResetNativePointer(void* native_pointer)
native_pointer_ = native_pointer; native_pointer_ = native_pointer;
} }
// #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
// NativeObject for Windows
//
#if defined(KGE_PLATFORM_WINDOWS)
NativeObject::~NativeObject() NativeObject::~NativeObject()
{ {

View File

@ -57,7 +57,7 @@ protected:
void* native_pointer_; void* native_pointer_;
}; };
#if defined(KGE_PLATFORM_WINDOWS) #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
class KGE_API NativeObject : public NativeObjectBase class KGE_API NativeObject : public NativeObjectBase
{ {
@ -65,6 +65,52 @@ public:
virtual ~NativeObject(); virtual ~NativeObject();
void ResetNativePointer(void* native_pointer = nullptr) override; void ResetNativePointer(void* native_pointer = nullptr) override;
template <typename _Ty, typename = typename std::enable_if<std::is_base_of<IUnknown, _Ty>::value, int>::type>
static inline ComPtr<_Ty> Get(const NativeObject* object)
{
if (object)
{
ComPtr<IUnknown> ptr = object->GetNativePointer<IUnknown>();
if (ptr)
{
ComPtr<_Ty> native;
if (SUCCEEDED(ptr->QueryInterface<_Ty>(&native)))
return native;
}
}
return nullptr;
}
template <typename _Ty>
static inline ComPtr<_Ty> Get(const NativeObject& object)
{
return NativeObject::Get<_Ty>(&object);
}
template <typename _Ty>
static inline ComPtr<_Ty> Get(NativeObjectPtr object)
{
return NativeObject::Get<_Ty>(object.Get());
}
static inline void Set(NativeObject* object, ComPtr<IUnknown> com_ptr)
{
if (object)
{
object->ResetNativePointer(com_ptr.Get());
}
}
static inline void Set(NativeObject& object, ComPtr<IUnknown> com_ptr)
{
NativeObject::Set(&object, com_ptr);
}
static inline void Set(NativeObjectPtr object, ComPtr<IUnknown> com_ptr)
{
NativeObject::Set(object.Get(), com_ptr);
}
}; };
#else #else

View File

@ -24,14 +24,9 @@
namespace kiwano namespace kiwano
{ {
RenderContextPtr RenderContext::Create(Texture& texture) RenderContextPtr RenderContext::Create(TexturePtr texture, const PixelSize& size)
{ {
return Renderer::GetInstance().CreateTextureRenderContext(texture, nullptr); return Renderer::GetInstance().CreateTextureRenderContext(texture, size);
}
RenderContextPtr RenderContext::Create(Texture& texture, const Size& size)
{
return Renderer::GetInstance().CreateTextureRenderContext(texture, &size);
} }
RenderContext::RenderContext() RenderContext::RenderContext()

View File

@ -52,16 +52,11 @@ enum class TextAntialiasMode
class KGE_API RenderContext : public NativeObject class KGE_API RenderContext : public NativeObject
{ {
public: public:
/// \~chinese
/// @brief 创建纹理渲染上下文,将绘制结果输出到纹理中
/// @param texture 保存绘制结果的纹理
static RenderContextPtr Create(Texture& texture);
/// \~chinese /// \~chinese
/// @brief 创建纹理渲染上下文,将绘制结果输出到纹理中 /// @brief 创建纹理渲染上下文,将绘制结果输出到纹理中
/// @param texture 保存绘制结果的纹理 /// @param texture 保存绘制结果的纹理
/// @param size 渲染输出大小 /// @param size 渲染输出大小
static RenderContextPtr Create(Texture& texture, const Size& size); static RenderContextPtr Create(TexturePtr texture, const PixelSize& size);
/// \~chinese /// \~chinese
/// @brief 开始渲染 /// @brief 开始渲染
@ -71,6 +66,12 @@ public:
/// @brief 结束渲染 /// @brief 结束渲染
virtual void EndDraw(); virtual void EndDraw();
/// \~chinese
/// @brief 创建空纹理
/// @param[out] texture 输出纹理
/// @param[in] size 纹理像素大小
virtual void CreateTexture(Texture& texture, const PixelSize& size) = 0;
/// \~chinese /// \~chinese
/// @brief 绘制纹理 /// @brief 绘制纹理
/// @param texture 纹理 /// @param texture 纹理
@ -148,12 +149,6 @@ public:
/// @param radius 椭圆半径 /// @param radius 椭圆半径
virtual void FillEllipse(const Point& center, const Vec2& radius) = 0; virtual void FillEllipse(const Point& center, const Vec2& radius) = 0;
/// \~chinese
/// @brief 创建纹理
/// @param texture 纹理
/// @param size 纹理像素大小
virtual void CreateTexture(Texture& texture, math::Vec2T<uint32_t> size) = 0;
/// \~chinese /// \~chinese
/// @brief 设置绘制的裁剪区域 /// @brief 设置绘制的裁剪区域
/// @param clip_rect 裁剪矩形 /// @param clip_rect 裁剪矩形
@ -237,6 +232,10 @@ public:
/// @brief 设置全局二维变换 /// @brief 设置全局二维变换
virtual void SetGlobalTransform(const Matrix3x2* matrix); virtual void SetGlobalTransform(const Matrix3x2* matrix);
/// \~chinese
/// @brief 获取渲染目标
virtual TexturePtr GetTarget() const = 0;
public: public:
/// \~chinese /// \~chinese
/// @brief 渲染上下文状态 /// @brief 渲染上下文状态

View File

@ -210,7 +210,7 @@ public:
/// @param[in,out] texture 渲染输出的纹理 /// @param[in,out] texture 渲染输出的纹理
/// @param[in] desired_size 期望的输出大小 /// @param[in] desired_size 期望的输出大小
/// @return 纹理渲染上下文 /// @return 纹理渲染上下文
virtual RenderContextPtr CreateTextureRenderContext(Texture& texture, const Size* desired_size = nullptr) = 0; virtual RenderContextPtr CreateTextureRenderContext(TexturePtr texture, const PixelSize& desired_size) = 0;
public: public:
/// \~chinese /// \~chinese

View File

@ -22,10 +22,6 @@
#include <kiwano/render/ShapeMaker.h> #include <kiwano/render/ShapeMaker.h>
#include <kiwano/render/Renderer.h> #include <kiwano/render/Renderer.h>
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
#include <kiwano/render/DirectX/NativePtr.h>
#endif
namespace kiwano namespace kiwano
{ {
@ -40,7 +36,7 @@ Rect Shape::GetBoundingBox() const
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
Rect bounds; Rect bounds;
auto geometry = NativePtr::Get<ID2D1Geometry>(this); auto geometry = NativeObject::Get<ID2D1Geometry>(this);
if (geometry) if (geometry)
{ {
// no matter it failed or not // 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 #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
Rect bounds; Rect bounds;
auto geometry = NativePtr::Get<ID2D1Geometry>(this); auto geometry = NativeObject::Get<ID2D1Geometry>(this);
if (geometry) if (geometry)
{ {
// no matter it failed or not // no matter it failed or not
@ -72,7 +68,7 @@ float Shape::GetLength() const
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
float length = 0.f; float length = 0.f;
auto geometry = NativePtr::Get<ID2D1Geometry>(this); auto geometry = NativeObject::Get<ID2D1Geometry>(this);
if (geometry) if (geometry)
{ {
// no matter it failed or not // no matter it failed or not
@ -87,7 +83,7 @@ float Shape::GetLength() const
bool Shape::ComputePointAtLength(float length, Point& point, Vec2& tangent) const bool Shape::ComputePointAtLength(float length, Point& point, Vec2& tangent) const
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto geometry = NativePtr::Get<ID2D1Geometry>(this); auto geometry = NativeObject::Get<ID2D1Geometry>(this);
if (geometry) if (geometry)
{ {
HRESULT hr = geometry->ComputePointAtLength(length, D2D1::Matrix3x2F::Identity(), DX::ConvertToPoint2F(&point), 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 float Shape::ComputeArea() const
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto geometry = NativePtr::Get<ID2D1Geometry>(this); auto geometry = NativeObject::Get<ID2D1Geometry>(this);
if (geometry) if (geometry)
{ {
float area = 0.f; float area = 0.f;
@ -120,7 +116,7 @@ float Shape::ComputeArea() const
bool Shape::ContainsPoint(const Point& point, const Matrix3x2* transform) const bool Shape::ContainsPoint(const Point& point, const Matrix3x2* transform) const
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto geometry = NativePtr::Get<ID2D1Geometry>(this); auto geometry = NativeObject::Get<ID2D1Geometry>(this);
if (!geometry) if (!geometry)
return false; return false;

View File

@ -21,10 +21,6 @@
#include <kiwano/render/ShapeMaker.h> #include <kiwano/render/ShapeMaker.h>
#include <kiwano/render/Renderer.h> #include <kiwano/render/Renderer.h>
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
#include <kiwano/render/DirectX/NativePtr.h>
#endif
namespace kiwano namespace kiwano
{ {
@ -59,7 +55,7 @@ void ShapeMaker::BeginPath(const Point& begin_pos)
} }
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<ID2D1GeometrySink>(this); auto native = NativeObject::Get<ID2D1GeometrySink>(this);
native->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED); native->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED);
#else #else
// not supported // not supported
@ -71,7 +67,7 @@ void ShapeMaker::EndPath(bool closed)
KGE_ASSERT(IsStreamOpened()); KGE_ASSERT(IsStreamOpened());
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<ID2D1GeometrySink>(this); auto native = NativeObject::Get<ID2D1GeometrySink>(this);
native->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN); native->EndFigure(closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN);
#else #else
// not supported // not supported
@ -85,7 +81,7 @@ void ShapeMaker::AddLine(const Point& point)
KGE_ASSERT(IsStreamOpened()); KGE_ASSERT(IsStreamOpened());
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<ID2D1GeometrySink>(this); auto native = NativeObject::Get<ID2D1GeometrySink>(this);
native->AddLine(DX::ConvertToPoint2F(point)); native->AddLine(DX::ConvertToPoint2F(point));
#else #else
// not supported // not supported
@ -97,7 +93,7 @@ void ShapeMaker::AddLines(const Vector<Point>& points)
KGE_ASSERT(IsStreamOpened()); KGE_ASSERT(IsStreamOpened());
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<ID2D1GeometrySink>(this); auto native = NativeObject::Get<ID2D1GeometrySink>(this);
native->AddLines(reinterpret_cast<const D2D_POINT_2F*>(&points[0]), static_cast<uint32_t>(points.size())); native->AddLines(reinterpret_cast<const D2D_POINT_2F*>(&points[0]), static_cast<uint32_t>(points.size()));
#else #else
// not supported // not supported
@ -109,7 +105,7 @@ void kiwano::ShapeMaker::AddLines(const Point* points, size_t count)
KGE_ASSERT(IsStreamOpened()); KGE_ASSERT(IsStreamOpened());
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<ID2D1GeometrySink>(this); auto native = NativeObject::Get<ID2D1GeometrySink>(this);
native->AddLines(reinterpret_cast<const D2D_POINT_2F*>(points), UINT32(count)); native->AddLines(reinterpret_cast<const D2D_POINT_2F*>(points), UINT32(count));
#else #else
// not supported // not supported
@ -121,7 +117,7 @@ void ShapeMaker::AddBezier(const Point& point1, const Point& point2, const Point
KGE_ASSERT(IsStreamOpened()); KGE_ASSERT(IsStreamOpened());
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<ID2D1GeometrySink>(this); auto native = NativeObject::Get<ID2D1GeometrySink>(this);
native->AddBezier( native->AddBezier(
D2D1::BezierSegment(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2), DX::ConvertToPoint2F(point3))); D2D1::BezierSegment(DX::ConvertToPoint2F(point1), DX::ConvertToPoint2F(point2), DX::ConvertToPoint2F(point3)));
#else #else
@ -134,7 +130,7 @@ void ShapeMaker::AddArc(const Point& point, const Size& radius, float rotation,
KGE_ASSERT(IsStreamOpened()); KGE_ASSERT(IsStreamOpened());
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<ID2D1GeometrySink>(this); auto native = NativeObject::Get<ID2D1GeometrySink>(this);
native->AddArc(D2D1::ArcSegment(DX::ConvertToPoint2F(point), DX::ConvertToSizeF(radius), rotation, native->AddArc(D2D1::ArcSegment(DX::ConvertToPoint2F(point), DX::ConvertToSizeF(radius), rotation,
clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,
is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE)); 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 KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (shape_a && shape_b) if (shape_a && shape_b)
{ {
auto geo_a = NativePtr::Get<ID2D1Geometry>(shape_a); auto geo_a = NativeObject::Get<ID2D1Geometry>(shape_a);
auto geo_b = NativePtr::Get<ID2D1Geometry>(shape_b); auto geo_b = NativeObject::Get<ID2D1Geometry>(shape_b);
auto native = NativePtr::Get<ID2D1GeometrySink>(maker); auto native = NativeObject::Get<ID2D1GeometrySink>(maker);
HRESULT hr = geo_a->CombineWithGeometry(geo_b.Get(), D2D1_COMBINE_MODE(mode), DX::ConvertToMatrix3x2F(matrix), HRESULT hr = geo_a->CombineWithGeometry(geo_b.Get(), D2D1_COMBINE_MODE(mode), DX::ConvertToMatrix3x2F(matrix),
native.Get()); native.Get());
@ -176,7 +172,7 @@ void ShapeMaker::OpenStream()
Renderer::GetInstance().CreateShapeSink(*this); Renderer::GetInstance().CreateShapeSink(*this);
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto geometry = NativePtr::Get<ID2D1PathGeometry>(shape_); auto geometry = NativeObject::Get<ID2D1PathGeometry>(shape_);
if (geometry) if (geometry)
{ {
ComPtr<ID2D1GeometrySink> native; ComPtr<ID2D1GeometrySink> native;
@ -184,7 +180,7 @@ void ShapeMaker::OpenStream()
HRESULT hr = geometry->Open(&native); HRESULT hr = geometry->Open(&native);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
NativePtr::Set(this, native); NativeObject::Set(this, native);
} }
KGE_THROW_IF_FAILED(hr, "ID2D1PathGeometry::Open failed"); KGE_THROW_IF_FAILED(hr, "ID2D1PathGeometry::Open failed");
} }
@ -199,7 +195,7 @@ void ShapeMaker::CloseStream()
return; return;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<ID2D1GeometrySink>(this); auto native = NativeObject::Get<ID2D1GeometrySink>(this);
HRESULT hr = native->Close(); HRESULT hr = native->Close();
KGE_THROW_IF_FAILED(hr, "ID2D1PathGeometry::Close failed"); KGE_THROW_IF_FAILED(hr, "ID2D1PathGeometry::Close failed");

View File

@ -21,10 +21,6 @@
#include <kiwano/render/Renderer.h> #include <kiwano/render/Renderer.h>
#include <kiwano/render/TextLayout.h> #include <kiwano/render/TextLayout.h>
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
#include <kiwano/render/DirectX/NativePtr.h>
#endif
namespace kiwano namespace kiwano
{ {
@ -84,7 +80,7 @@ void TextLayout::SetFont(FontPtr font)
return; return;
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this); auto native = NativeObject::Get<IDWriteTextLayout>(this);
KGE_ASSERT(native); KGE_ASSERT(native);
if (native) if (native)
@ -93,7 +89,7 @@ void TextLayout::SetFont(FontPtr font)
// reset font collection // reset font collection
{ {
auto collection = NativePtr::Get<IDWriteFontCollection>(font); auto collection = NativeObject::Get<IDWriteFontCollection>(font);
hr = native->SetFontCollection(collection.Get(), { 0, content_length_ }); hr = native->SetFontCollection(collection.Get(), { 0, content_length_ });
KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontCollection failed"); KGE_THROW_IF_FAILED(hr, "IDWriteTextLayout::SetFontCollection failed");
@ -148,7 +144,7 @@ void TextLayout::SetFont(FontPtr font)
void TextLayout::SetUnderline(bool enable) void TextLayout::SetUnderline(bool enable)
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this); auto native = NativeObject::Get<IDWriteTextLayout>(this);
KGE_ASSERT(native); KGE_ASSERT(native);
if (native) if (native)
@ -166,7 +162,7 @@ void TextLayout::SetUnderline(bool enable)
void TextLayout::SetStrikethrough(bool enable) void TextLayout::SetStrikethrough(bool enable)
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this); auto native = NativeObject::Get<IDWriteTextLayout>(this);
KGE_ASSERT(native); KGE_ASSERT(native);
if (native) if (native)
@ -184,7 +180,7 @@ void TextLayout::SetStrikethrough(bool enable)
void TextLayout::SetAlignment(TextAlign align) void TextLayout::SetAlignment(TextAlign align)
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this); auto native = NativeObject::Get<IDWriteTextLayout>(this);
KGE_ASSERT(native); KGE_ASSERT(native);
if (native) if (native)
@ -219,7 +215,7 @@ void TextLayout::SetAlignment(TextAlign align)
void TextLayout::SetWrapWidth(float wrap_width) void TextLayout::SetWrapWidth(float wrap_width)
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this); auto native = NativeObject::Get<IDWriteTextLayout>(this);
KGE_ASSERT(native); KGE_ASSERT(native);
if (native) if (native)
@ -249,7 +245,7 @@ void TextLayout::SetWrapWidth(float wrap_width)
void TextLayout::SetLineSpacing(float line_spacing) void TextLayout::SetLineSpacing(float line_spacing)
{ {
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
auto native = NativePtr::Get<IDWriteTextLayout>(this); auto native = NativeObject::Get<IDWriteTextLayout>(this);
KGE_ASSERT(native); KGE_ASSERT(native);
if (native) if (native)
@ -284,7 +280,7 @@ bool TextLayout::UpdateIfDirty()
line_count_ = 0; line_count_ = 0;
size_ = Size(); size_ = Size();
auto native = NativePtr::Get<IDWriteTextLayout>(this); auto native = NativeObject::Get<IDWriteTextLayout>(this);
if (content_length_ == 0 || !native) if (content_length_ == 0 || !native)
return true; return true;

View File

@ -23,10 +23,6 @@
#include <kiwano/render/TextureCache.h> #include <kiwano/render/TextureCache.h>
#include <functional> // std::hash #include <functional> // std::hash
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
#include <kiwano/render/DirectX/NativePtr.h>
#endif
namespace kiwano namespace kiwano
{ {
@ -108,8 +104,8 @@ void Texture::CopyFrom(TexturePtr copy_from)
#if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX #if KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (IsValid() && copy_from) if (IsValid() && copy_from)
{ {
auto native = NativePtr::Get<ID2D1Bitmap>(this); auto native = NativeObject::Get<ID2D1Bitmap>(this);
auto native_to_copy = NativePtr::Get<ID2D1Bitmap>(copy_from); auto native_to_copy = NativeObject::Get<ID2D1Bitmap>(copy_from);
HRESULT hr = native->CopyFromBitmap(nullptr, native_to_copy.Get(), nullptr); 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 KGE_RENDER_ENGINE == KGE_RENDER_ENGINE_DIRECTX
if (IsValid() && copy_from) if (IsValid() && copy_from)
{ {
auto native = NativePtr::Get<ID2D1Bitmap>(this); auto native = NativeObject::Get<ID2D1Bitmap>(this);
auto native_to_copy = NativePtr::Get<ID2D1Bitmap>(copy_from); auto native_to_copy = NativeObject::Get<ID2D1Bitmap>(copy_from);
HRESULT hr = HRESULT hr =
native->CopyFromBitmap(&D2D1::Point2U(uint32_t(dest_point.x), uint32_t(dest_point.y)), native_to_copy.Get(), native->CopyFromBitmap(&D2D1::Point2U(uint32_t(dest_point.x), uint32_t(dest_point.y)), native_to_copy.Get(),

View File

@ -54,7 +54,6 @@ typedef math::Vec2T<uint32_t> PixelSize;
*/ */
enum class PixelFormat enum class PixelFormat
{ {
Bpp32RGB,
Bpp32RGBA, Bpp32RGBA,
Bpp32BGR, Bpp32BGR,
Bpp32BGRA, Bpp32BGRA,