diff --git a/projects/kiwano/kiwano.vcxproj b/projects/kiwano/kiwano.vcxproj
index 2fbffc54..02f57773 100644
--- a/projects/kiwano/kiwano.vcxproj
+++ b/projects/kiwano/kiwano.vcxproj
@@ -75,6 +75,7 @@
+
diff --git a/projects/kiwano/kiwano.vcxproj.filters b/projects/kiwano/kiwano.vcxproj.filters
index e008fce2..e2f3e4d4 100644
--- a/projects/kiwano/kiwano.vcxproj.filters
+++ b/projects/kiwano/kiwano.vcxproj.filters
@@ -267,6 +267,9 @@
renderer
+
+ renderer\win32
+
diff --git a/src/kiwano/2d/Stage.cpp b/src/kiwano/2d/Stage.cpp
index 1a8b676e..2e95a1ef 100644
--- a/src/kiwano/2d/Stage.cpp
+++ b/src/kiwano/2d/Stage.cpp
@@ -38,12 +38,12 @@ namespace kiwano
void Stage::OnEnter()
{
- // KGE_SYS_LOG(L"Stage entered");
+ KGE_SYS_LOG(L"Stage entered");
}
void Stage::OnExit()
{
- // KGE_SYS_LOG(L"Stage exited");
+ KGE_SYS_LOG(L"Stage exited");
}
void Stage::RenderBorder(RenderTarget* rt)
diff --git a/src/kiwano/core/win32/helper.h b/src/kiwano/core/win32/helper.h
index b7b5e0bf..a8c1d8b7 100644
--- a/src/kiwano/core/win32/helper.h
+++ b/src/kiwano/core/win32/helper.h
@@ -18,18 +18,16 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-#include
+#include
+#include
#include <3rd-party/StackWalker/StackWalker.h>
namespace kiwano
{
- // Display stack trace on exception
inline void ThrowIfFailed(HRESULT hr)
{
if (FAILED(hr))
{
- KGE_ERROR(L"Failed with HRESULT of %08X", hr);
-
StackWalker{}.ShowCallstack();
static char buffer[1024 + 1];
diff --git a/src/kiwano/platform/Application.cpp b/src/kiwano/platform/Application.cpp
index 07edba88..25f1cdb1 100644
--- a/src/kiwano/platform/Application.cpp
+++ b/src/kiwano/platform/Application.cpp
@@ -22,6 +22,7 @@
#include
#include
+#include
#include
#include
#include
@@ -148,8 +149,6 @@ namespace kiwano
comps_.clear();
}
- Input::instance().Destroy();
- Renderer::instance().Destroy();
Window::instance().Destroy();
}
@@ -304,14 +303,12 @@ namespace kiwano
{
KeyDownEvent evt;
evt.code = static_cast(wparam);
- // evt.count = static_cast(lparam & 0xFF);
app->DispatchEvent(evt);
}
else
{
KeyUpEvent evt;
evt.code = static_cast(wparam);
- // evt.count = static_cast(lparam & 0xFF);
app->DispatchEvent(evt);
}
}
@@ -321,7 +318,6 @@ namespace kiwano
{
KeyCharEvent evt;
evt.value = static_cast(wparam);
- // evt.count = static_cast(lparam & 0xFF);
app->DispatchEvent(evt);
}
break;
@@ -383,7 +379,7 @@ namespace kiwano
{
if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam)
{
- // KGE_SYS_LOG(L"Window minimized");
+ KGE_SYS_LOG(L"Window minimized");
}
else
{
@@ -425,7 +421,7 @@ namespace kiwano
case WM_SETTEXT:
{
- // KGE_SYS_LOG(L"Window title changed");
+ KGE_SYS_LOG(L"Window title changed");
WindowTitleChangedEvent evt;
evt.title = reinterpret_cast(lparam);
@@ -435,13 +431,13 @@ namespace kiwano
case WM_SETICON:
{
- // KGE_SYS_LOG(L"Window icon changed");
+ KGE_SYS_LOG(L"Window icon changed");
}
break;
case WM_DISPLAYCHANGE:
{
- // KGE_SYS_LOG(L"The display resolution has changed");
+ KGE_SYS_LOG(L"The display resolution has changed");
::InvalidateRect(hwnd, nullptr, FALSE);
}
@@ -455,7 +451,7 @@ namespace kiwano
case WM_CLOSE:
{
- // KGE_SYS_LOG(L"Window is closing");
+ KGE_SYS_LOG(L"Window is closing");
if (!app->OnClosing())
{
diff --git a/src/kiwano/platform/Input.cpp b/src/kiwano/platform/Input.cpp
index 98416b96..9803760c 100644
--- a/src/kiwano/platform/Input.cpp
+++ b/src/kiwano/platform/Input.cpp
@@ -140,8 +140,4 @@ namespace kiwano
{
return Point{ mouse_pos_x_, mouse_pos_y_ };
}
-
- void Input::Destroy()
- {
- }
}
diff --git a/src/kiwano/platform/Input.h b/src/kiwano/platform/Input.h
index 2bdd7d11..0daebfab 100644
--- a/src/kiwano/platform/Input.h
+++ b/src/kiwano/platform/Input.h
@@ -100,8 +100,6 @@ namespace kiwano
void UpdateMousePos(float, float);
- void Destroy();
-
private:
Input();
diff --git a/src/kiwano/platform/Window.cpp b/src/kiwano/platform/Window.cpp
index f70f6a19..5f7f5cef 100644
--- a/src/kiwano/platform/Window.cpp
+++ b/src/kiwano/platform/Window.cpp
@@ -20,6 +20,7 @@
#include
#include
+#include
#include
#define WINDOW_FIXED_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
diff --git a/src/kiwano/renderer/RenderTarget.cpp b/src/kiwano/renderer/RenderTarget.cpp
index 22192bb8..14a1bf27 100644
--- a/src/kiwano/renderer/RenderTarget.cpp
+++ b/src/kiwano/renderer/RenderTarget.cpp
@@ -20,6 +20,7 @@
#include
#include
+#include
namespace kiwano
{
@@ -36,32 +37,64 @@ namespace kiwano
status_.primitives = 0;
}
- HRESULT RenderTarget::CreateDeviceResources(ComPtr rt, ComPtr dev_res)
+ HRESULT RenderTarget::CreateDeviceResources(ComPtr factory, ComPtr rt)
{
- HRESULT hr = E_FAIL;
+ if (!factory || !rt)
+ return E_INVALIDARG;
- if (rt && dev_res)
- {
- render_target_ = rt;
- device_resources_ = dev_res;
- hr = S_OK;
- }
+ render_target_ = rt;
+ text_renderer_.reset();
+ current_brush_.reset();
- if (SUCCEEDED(hr))
- {
- text_renderer_.reset();
- hr = ITextRenderer::Create(
- &text_renderer_,
- render_target_.get()
- );
- }
+ HRESULT hr = ITextRenderer::Create(
+ &text_renderer_,
+ render_target_.get()
+ );
if (SUCCEEDED(hr))
{
SetAntialiasMode(antialias_);
SetTextAntialiasMode(text_antialias_);
- current_brush_.reset();
+ Resize(reinterpret_cast(GetRenderTarget()->GetSize()));
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ ComPtr miter_stroke_style;
+ ComPtr bevel_stroke_style;
+ ComPtr round_stroke_style;
+
+ D2D1_STROKE_STYLE_PROPERTIES stroke_style = D2D1::StrokeStyleProperties(
+ D2D1_CAP_STYLE_FLAT,
+ D2D1_CAP_STYLE_FLAT,
+ D2D1_CAP_STYLE_FLAT,
+ D2D1_LINE_JOIN_MITER,
+ 2.0f,
+ D2D1_DASH_STYLE_SOLID,
+ 0.0f
+ );
+
+ hr = factory->CreateStrokeStyle(stroke_style, nullptr, 0, &miter_stroke_style);
+
+ if (SUCCEEDED(hr))
+ {
+ stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL;
+ hr = factory->CreateStrokeStyle(stroke_style, nullptr, 0, &bevel_stroke_style);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND;
+ hr = factory->CreateStrokeStyle(stroke_style, nullptr, 0, &round_stroke_style);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ miter_stroke_style_ = miter_stroke_style;
+ bevel_stroke_style_ = bevel_stroke_style;
+ round_stroke_style_ = round_stroke_style;
+ }
}
return hr;
@@ -69,15 +102,18 @@ namespace kiwano
void RenderTarget::DiscardDeviceResources()
{
+ miter_stroke_style_.reset();
+ bevel_stroke_style_.reset();
+ round_stroke_style_.reset();
+
text_renderer_.reset();
render_target_.reset();
current_brush_.reset();
- device_resources_.reset();
}
bool RenderTarget::IsValid() const
{
- return render_target_ && device_resources_;
+ return render_target_ != nullptr;
}
void RenderTarget::BeginDraw()
@@ -106,13 +142,10 @@ namespace kiwano
void RenderTarget::DrawGeometry(Geometry const& geometry, float stroke_width, StrokeStyle stroke)
{
- HRESULT hr = S_OK;
- if (!render_target_ || !current_brush_)
- {
- hr = E_UNEXPECTED;
- }
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+ KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
- if (SUCCEEDED(hr) && geometry.GetGeometry())
+ if (geometry.IsValid())
{
render_target_->DrawGeometry(
geometry.GetGeometry().get(),
@@ -123,19 +156,14 @@ namespace kiwano
IncreasePrimitivesCount();
}
-
- ThrowIfFailed(hr);
}
void RenderTarget::FillGeometry(Geometry const& geometry)
{
- HRESULT hr = S_OK;
- if (!render_target_ || !current_brush_)
- {
- hr = E_UNEXPECTED;
- }
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+ KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
- if (SUCCEEDED(hr) && geometry.GetGeometry())
+ if (geometry.IsValid())
{
render_target_->FillGeometry(
geometry.GetGeometry().get(),
@@ -144,181 +172,122 @@ namespace kiwano
IncreasePrimitivesCount();
}
-
- ThrowIfFailed(hr);
}
void RenderTarget::DrawLine(Point const& point1, Point const& point2, float stroke_width, StrokeStyle stroke)
{
- HRESULT hr = S_OK;
- if (!render_target_ || !current_brush_)
- {
- hr = E_UNEXPECTED;
- }
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+ KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
- if (SUCCEEDED(hr))
- {
- render_target_->DrawLine(
- DX::ConvertToPoint2F(point1),
- DX::ConvertToPoint2F(point2),
- current_brush_->GetBrush().get(),
- stroke_width,
- GetStrokeStyle(stroke).get()
- );
+ render_target_->DrawLine(
+ DX::ConvertToPoint2F(point1),
+ DX::ConvertToPoint2F(point2),
+ current_brush_->GetBrush().get(),
+ stroke_width,
+ GetStrokeStyle(stroke).get()
+ );
- IncreasePrimitivesCount();
- }
-
- ThrowIfFailed(hr);
+ IncreasePrimitivesCount();
}
void RenderTarget::DrawRectangle(Rect const& rect, float stroke_width, StrokeStyle stroke)
{
- HRESULT hr = S_OK;
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+ KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
- if (!render_target_ || !current_brush_)
- {
- hr = E_UNEXPECTED;
- }
+ render_target_->DrawRectangle(
+ DX::ConvertToRectF(rect),
+ current_brush_->GetBrush().get(),
+ stroke_width,
+ GetStrokeStyle(stroke).get()
+ );
- if (SUCCEEDED(hr))
- {
- render_target_->DrawRectangle(
- DX::ConvertToRectF(rect),
- current_brush_->GetBrush().get(),
- stroke_width,
- GetStrokeStyle(stroke).get()
- );
-
- IncreasePrimitivesCount();
- }
-
- ThrowIfFailed(hr);
+ IncreasePrimitivesCount();
}
void RenderTarget::FillRectangle(Rect const& rect)
{
- HRESULT hr = S_OK;
- if (!render_target_ || !current_brush_)
- {
- hr = E_UNEXPECTED;
- }
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+ KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
- if (SUCCEEDED(hr))
- {
- render_target_->FillRectangle(
- DX::ConvertToRectF(rect),
- current_brush_->GetBrush().get()
- );
+ render_target_->FillRectangle(
+ DX::ConvertToRectF(rect),
+ current_brush_->GetBrush().get()
+ );
- IncreasePrimitivesCount();
- }
-
- ThrowIfFailed(hr);
+ IncreasePrimitivesCount();
}
void RenderTarget::DrawRoundedRectangle(Rect const& rect, Vec2 const& radius, float stroke_width, StrokeStyle stroke)
{
- HRESULT hr = S_OK;
- if (!render_target_ || !current_brush_)
- {
- hr = E_UNEXPECTED;
- }
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+ KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
- if (SUCCEEDED(hr))
- {
- render_target_->DrawRoundedRectangle(
- D2D1::RoundedRect(
- DX::ConvertToRectF(rect),
- radius.x,
- radius.y
- ),
- current_brush_->GetBrush().get(),
- stroke_width,
- GetStrokeStyle(stroke).get()
- );
+ render_target_->DrawRoundedRectangle(
+ D2D1::RoundedRect(
+ DX::ConvertToRectF(rect),
+ radius.x,
+ radius.y
+ ),
+ current_brush_->GetBrush().get(),
+ stroke_width,
+ GetStrokeStyle(stroke).get()
+ );
- IncreasePrimitivesCount();
- }
-
- ThrowIfFailed(hr);
+ IncreasePrimitivesCount();
}
void RenderTarget::FillRoundedRectangle(Rect const& rect, Vec2 const& radius)
{
- HRESULT hr = S_OK;
- if (!render_target_ || !current_brush_)
- {
- hr = E_UNEXPECTED;
- }
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+ KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
- if (SUCCEEDED(hr))
- {
- render_target_->FillRoundedRectangle(
- D2D1::RoundedRect(
- DX::ConvertToRectF(rect),
- radius.x,
- radius.y
- ),
- current_brush_->GetBrush().get()
- );
+ render_target_->FillRoundedRectangle(
+ D2D1::RoundedRect(
+ DX::ConvertToRectF(rect),
+ radius.x,
+ radius.y
+ ),
+ current_brush_->GetBrush().get()
+ );
- IncreasePrimitivesCount();
- }
-
- ThrowIfFailed(hr);
+ IncreasePrimitivesCount();
}
void RenderTarget::DrawEllipse(Point const& center, Vec2 const& radius, float stroke_width, StrokeStyle stroke)
{
- HRESULT hr = S_OK;
- if (!render_target_ || !current_brush_)
- {
- hr = E_UNEXPECTED;
- }
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+ KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
- if (SUCCEEDED(hr))
- {
- render_target_->DrawEllipse(
- D2D1::Ellipse(
- DX::ConvertToPoint2F(center),
- radius.x,
- radius.y
- ),
- current_brush_->GetBrush().get(),
- stroke_width,
- GetStrokeStyle(stroke).get()
- );
+ render_target_->DrawEllipse(
+ D2D1::Ellipse(
+ DX::ConvertToPoint2F(center),
+ radius.x,
+ radius.y
+ ),
+ current_brush_->GetBrush().get(),
+ stroke_width,
+ GetStrokeStyle(stroke).get()
+ );
- IncreasePrimitivesCount();
- }
-
- ThrowIfFailed(hr);
+ IncreasePrimitivesCount();
}
void RenderTarget::FillEllipse(Point const& center, Vec2 const& radius)
{
- HRESULT hr = S_OK;
- if (!render_target_ || !current_brush_)
- {
- hr = E_UNEXPECTED;
- }
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+ KGE_ASSERT(current_brush_ && "The brush used for rendering has not been set!");
- if (SUCCEEDED(hr))
- {
- render_target_->FillEllipse(
- D2D1::Ellipse(
- DX::ConvertToPoint2F(center),
- radius.x,
- radius.y
- ),
- current_brush_->GetBrush().get()
- );
+ render_target_->FillEllipse(
+ D2D1::Ellipse(
+ DX::ConvertToPoint2F(center),
+ radius.x,
+ radius.y
+ ),
+ current_brush_->GetBrush().get()
+ );
- IncreasePrimitivesCount();
- }
-
- ThrowIfFailed(hr);
+ IncreasePrimitivesCount();
}
void RenderTarget::DrawTexture(Texture const& texture, Rect const& src_rect, Rect const& dest_rect, float opacity)
@@ -328,13 +297,9 @@ namespace kiwano
void RenderTarget::DrawTexture(Texture const& texture, const Rect* src_rect, const Rect* dest_rect, float opacity)
{
- HRESULT hr = S_OK;
- if (!render_target_)
- {
- hr = E_UNEXPECTED;
- }
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
- if (SUCCEEDED(hr) && texture.IsValid())
+ if (texture.IsValid())
{
auto mode = (texture.GetBitmapInterpolationMode() == InterpolationMode::Linear)
? D2D1_BITMAP_INTERPOLATION_MODE_LINEAR
@@ -350,134 +315,87 @@ namespace kiwano
IncreasePrimitivesCount();
}
-
- ThrowIfFailed(hr);
}
void RenderTarget::DrawTextLayout(TextLayout const& layout, Point const& offset)
{
- HRESULT hr = S_OK;
- if (!text_renderer_)
- {
- hr = E_UNEXPECTED;
- }
+ KGE_ASSERT(text_renderer_ && "Text renderer has not been initialized!");
- if (SUCCEEDED(hr))
- {
- const TextStyle& style = layout.GetStyle();
- text_renderer_->SetStyle(
- style.fill_brush ? style.fill_brush->GetBrush().get() : nullptr,
- style.outline_brush ? style.outline_brush->GetBrush().get() : nullptr,
- style.outline_width,
- GetStrokeStyle(style.outline_stroke).get()
- );
+ const TextStyle& style = layout.GetStyle();
+ text_renderer_->SetStyle(
+ style.fill_brush ? style.fill_brush->GetBrush().get() : nullptr,
+ style.outline_brush ? style.outline_brush->GetBrush().get() : nullptr,
+ style.outline_width,
+ GetStrokeStyle(style.outline_stroke).get()
+ );
- hr = layout.GetTextLayout()->Draw(nullptr, text_renderer_.get(), offset.x, offset.y);
- }
+ HRESULT hr = layout.GetTextLayout()->Draw(nullptr, text_renderer_.get(), offset.x, offset.y);
if (SUCCEEDED(hr))
{
IncreasePrimitivesCount();
}
-
- ThrowIfFailed(hr);
+ else
+ {
+ KGE_ERROR(L"Failed to draw text layout with HRESULT of %08X", hr);
+ }
}
void RenderTarget::CreateTexture(Texture& texture, math::Vec2T size, D2D1_PIXEL_FORMAT format)
{
- HRESULT hr = S_OK;
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
- if (!render_target_)
- {
- hr = E_UNEXPECTED;
- }
+ ComPtr saved_bitmap;
+ HRESULT hr = render_target_->CreateBitmap(
+ D2D1::SizeU(size.x, size.y),
+ D2D1::BitmapProperties(format),
+ &saved_bitmap
+ );
if (SUCCEEDED(hr))
{
- ComPtr saved_bitmap;
- hr = render_target_->CreateBitmap(D2D1::SizeU(size.x, size.y), D2D1::BitmapProperties(format), &saved_bitmap);
-
- if (SUCCEEDED(hr))
- {
- texture.SetBitmap(saved_bitmap);
- }
+ texture.SetBitmap(saved_bitmap);
+ }
+ else
+ {
+ ThrowIfFailed(hr);
}
-
- ThrowIfFailed(hr);
}
- void RenderTarget::CreateLayer(LayerArea& layer)
+ void RenderTarget::PushClipRect(Rect const& clip_rect)
{
- HRESULT hr = S_OK;
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+ render_target_->PushAxisAlignedClip(
+ DX::ConvertToRectF(clip_rect),
+ antialias_ ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED
+ );
+ }
- if (!render_target_)
- {
- hr = E_UNEXPECTED;
- }
+ void RenderTarget::PopClipRect()
+ {
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+ render_target_->PopAxisAlignedClip();
+ }
- if (SUCCEEDED(hr))
+ void RenderTarget::PushLayer(LayerArea& layer)
+ {
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+ if (!layer.IsValid())
{
ComPtr output;
- hr = render_target_->CreateLayer(&output);
+ HRESULT hr = render_target_->CreateLayer(&output);
if (SUCCEEDED(hr))
{
layer.SetLayer(output);
}
+ else
+ {
+ ThrowIfFailed(hr);
+ }
}
- ThrowIfFailed(hr);
- }
-
- void RenderTarget::PushClipRect(Rect const& clip_rect)
- {
- HRESULT hr = S_OK;
- if (!render_target_)
- {
- hr = E_UNEXPECTED;
- }
-
- if (SUCCEEDED(hr))
- {
- render_target_->PushAxisAlignedClip(
- DX::ConvertToRectF(clip_rect),
- antialias_ ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED
- );
- }
-
- ThrowIfFailed(hr);
- }
-
- void RenderTarget::PopClipRect()
- {
- HRESULT hr = S_OK;
- if (!render_target_)
- {
- hr = E_UNEXPECTED;
- }
-
- if (SUCCEEDED(hr))
- {
- render_target_->PopAxisAlignedClip();
- }
-
- ThrowIfFailed(hr);
- }
-
- void RenderTarget::PushLayer(LayerArea& layer)
- {
- HRESULT hr = S_OK;
- if (!render_target_)
- {
- hr = E_UNEXPECTED;
- }
-
- if (!layer.IsValid())
- {
- CreateLayer(layer);
- }
-
- if (SUCCEEDED(hr) && layer.IsValid())
+ if (layer.IsValid())
{
render_target_->PushLayer(
D2D1::LayerParameters(
@@ -492,85 +410,50 @@ namespace kiwano
layer.GetLayer().get()
);
}
-
- ThrowIfFailed(hr);
}
void RenderTarget::PopLayer()
{
- HRESULT hr = S_OK;
- if (!render_target_)
- {
- hr = E_UNEXPECTED;
- }
-
- if (SUCCEEDED(hr))
- {
- render_target_->PopLayer();
- }
-
- ThrowIfFailed(hr);
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+ render_target_->PopLayer();
}
void RenderTarget::Clear()
{
- HRESULT hr = E_FAIL;
-
- if (render_target_)
- {
- render_target_->Clear();
- hr = S_OK;
- }
-
- ThrowIfFailed(hr);
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+ render_target_->Clear();
}
void RenderTarget::Clear(Color const& clear_color)
{
- HRESULT hr = E_FAIL;
-
- if (render_target_)
- {
- render_target_->Clear(DX::ConvertToColorF(clear_color));
- hr = S_OK;
- }
-
- ThrowIfFailed(hr);
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+ render_target_->Clear(DX::ConvertToColorF(clear_color));
}
ComPtr RenderTarget::GetStrokeStyle(StrokeStyle style)
{
switch (style)
{
- case StrokeStyle::Miter: return device_resources_->GetMiterStrokeStyle(); break;
- case StrokeStyle::Bevel: return device_resources_->GetBevelStrokeStyle(); break;
- case StrokeStyle::Round: return device_resources_->GetRoundStrokeStyle(); break;
+ case StrokeStyle::Miter: return miter_stroke_style_;
+ case StrokeStyle::Bevel: return bevel_stroke_style_;
+ case StrokeStyle::Round: return round_stroke_style_;
}
return nullptr;
}
void RenderTarget::SetTransform(const Matrix3x2& matrix)
{
- HRESULT hr = S_OK;
- if (!render_target_)
- {
- hr = E_UNEXPECTED;
- }
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
- if (SUCCEEDED(hr))
+ if (fast_global_transform_)
{
- if (fast_global_transform_)
- {
- render_target_->SetTransform(DX::ConvertToMatrix3x2F(&matrix));
- }
- else
- {
- Matrix3x2 result = matrix * global_transform_;
- render_target_->SetTransform(DX::ConvertToMatrix3x2F(&result));
- }
+ render_target_->SetTransform(DX::ConvertToMatrix3x2F(&matrix));
+ }
+ else
+ {
+ Matrix3x2 result = matrix * global_transform_;
+ render_target_->SetTransform(DX::ConvertToMatrix3x2F(&result));
}
-
- ThrowIfFailed(hr);
}
void RenderTarget::SetGlobalTransform(const Matrix3x2* matrix)
@@ -588,66 +471,53 @@ namespace kiwano
void RenderTarget::SetAntialiasMode(bool enabled)
{
- HRESULT hr = S_OK;
- if (!render_target_)
- {
- hr = E_UNEXPECTED;
- }
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
- if (SUCCEEDED(hr))
- {
- render_target_->SetAntialiasMode(
- enabled ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED
- );
- antialias_ = enabled;
- }
-
- ThrowIfFailed(hr);
+ render_target_->SetAntialiasMode(enabled ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED);
+ antialias_ = enabled;
}
void RenderTarget::SetTextAntialiasMode(TextAntialiasMode mode)
{
- HRESULT hr = S_OK;
- if (!render_target_)
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+
+ D2D1_TEXT_ANTIALIAS_MODE antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
+ switch (mode)
{
- hr = E_UNEXPECTED;
+ case TextAntialiasMode::Default:
+ antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
+ break;
+ case TextAntialiasMode::ClearType:
+ antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
+ break;
+ case TextAntialiasMode::GrayScale:
+ antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE;
+ break;
+ case TextAntialiasMode::None:
+ antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_ALIASED;
+ break;
+ default:
+ break;
}
- if (SUCCEEDED(hr))
- {
- text_antialias_ = mode;
- D2D1_TEXT_ANTIALIAS_MODE antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
- switch (text_antialias_)
- {
- case TextAntialiasMode::Default:
- antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_DEFAULT;
- break;
- case TextAntialiasMode::ClearType:
- antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
- break;
- case TextAntialiasMode::GrayScale:
- antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE;
- break;
- case TextAntialiasMode::None:
- antialias_mode = D2D1_TEXT_ANTIALIAS_MODE_ALIASED;
- break;
- default:
- break;
- }
- render_target_->SetTextAntialiasMode(antialias_mode);
- }
-
- ThrowIfFailed(hr);
+ text_antialias_ = mode;
+ render_target_->SetTextAntialiasMode(antialias_mode);
}
bool RenderTarget::CheckVisibility(Rect const& bounds, Matrix3x2 const& transform)
{
- Rect visible_size = { Point{}, reinterpret_cast(render_target_->GetSize()) };
+ KGE_ASSERT(render_target_ && "Render target has not been initialized!");
+
if (fast_global_transform_)
{
- return visible_size.Intersects(transform.Transform(bounds));
+ return visible_size_.Intersects(transform.Transform(bounds));
}
- return visible_size.Intersects(Matrix3x2(transform * global_transform_).Transform(bounds));
+ return visible_size_.Intersects(Matrix3x2(transform * global_transform_).Transform(bounds));
+ }
+
+ void RenderTarget::Resize(Size const& size)
+ {
+ visible_size_ = Rect(Point(), size);
}
void RenderTarget::SetCollectingStatus(bool collecting)
diff --git a/src/kiwano/renderer/RenderTarget.h b/src/kiwano/renderer/RenderTarget.h
index d9c0a1f3..ed3ffb36 100644
--- a/src/kiwano/renderer/RenderTarget.h
+++ b/src/kiwano/renderer/RenderTarget.h
@@ -50,6 +50,8 @@ namespace kiwano
class KGE_API RenderTarget
: public ObjectBase
{
+ friend class Renderer;
+
public:
bool IsValid() const;
@@ -133,27 +135,17 @@ namespace kiwano
D2D1_PIXEL_FORMAT format
);
- void CreateLayer(
- LayerArea& layer
- );
-
- void PushClipRect(
- Rect const& clip_rect
- );
+ void PushClipRect(Rect const& clip_rect);
void PopClipRect();
- void PushLayer(
- LayerArea& layer
- );
+ void PushLayer(LayerArea& layer);
void PopLayer();
void Clear();
- void Clear(
- Color const& clear_color
- );
+ void Clear(Color const& clear_color);
BrushPtr GetCurrentBrush() const;
@@ -191,6 +183,10 @@ namespace kiwano
Matrix3x2 const& transform
);
+ void Resize(
+ Size const& size
+ );
+
public:
struct Status
{
@@ -208,30 +204,34 @@ namespace kiwano
inline Status const& GetStatus() const { return status_; }
protected:
+ RenderTarget();
+
inline ComPtr GetRenderTarget() const { KGE_ASSERT(render_target_); return render_target_; }
inline ComPtr GetTextRenderer() const { KGE_ASSERT(text_renderer_); return text_renderer_; }
ComPtr GetStrokeStyle(StrokeStyle style);
- protected:
- RenderTarget();
-
- HRESULT CreateDeviceResources(ComPtr rt, ComPtr dev_res);
+ private:
+ HRESULT CreateDeviceResources(ComPtr factory, ComPtr rt);
void DiscardDeviceResources();
private:
bool antialias_;
bool fast_global_transform_;
- mutable bool collecting_status_;
- mutable Status status_;
TextAntialiasMode text_antialias_;
ComPtr text_renderer_;
ComPtr render_target_;
- ComPtr device_resources_;
+ ComPtr miter_stroke_style_;
+ ComPtr bevel_stroke_style_;
+ ComPtr round_stroke_style_;
BrushPtr current_brush_;
+ Rect visible_size_;
Matrix3x2 global_transform_;
+
+ mutable bool collecting_status_;
+ mutable Status status_;
};
diff --git a/src/kiwano/renderer/Renderer.cpp b/src/kiwano/renderer/Renderer.cpp
index f51d42ce..4f2a93ec 100644
--- a/src/kiwano/renderer/Renderer.cpp
+++ b/src/kiwano/renderer/Renderer.cpp
@@ -19,6 +19,7 @@
// THE SOFTWARE.
#include
+#include
#include
#include
#include
@@ -61,20 +62,16 @@ namespace kiwano
HRESULT hr = hwnd_ ? S_OK : E_FAIL;
- // Direct2D device resources
- if (SUCCEEDED(hr))
- {
- hr = ID2DDeviceResources::Create(&d2d_res_);
- }
-
// Direct3D device resources
if (SUCCEEDED(hr))
{
- hr = ID3DDeviceResources::Create(
- &d3d_res_,
- d2d_res_.get(),
- hwnd_
- );
+ hr = ID3DDeviceResources::Create(&d3d_res_, hwnd_);
+ }
+
+ // Direct2D device resources
+ if (SUCCEEDED(hr))
+ {
+ hr = ID2DDeviceResources::Create(&d2d_res_, d3d_res_->GetDXGIDevice(), d3d_res_->GetDXGISwapChain());
}
// DrawingStateBlock
@@ -88,7 +85,7 @@ namespace kiwano
// Other device resources
if (SUCCEEDED(hr))
{
- hr = CreateDeviceResources();
+ hr = CreateDeviceResources(d2d_res_->GetFactory(), d2d_res_->GetDeviceContext());
}
// FontFileLoader and FontCollectionLoader
@@ -130,7 +127,7 @@ namespace kiwano
{
KGE_SYS_LOG(L"Destroying device resources");
- RenderTarget::DiscardDeviceResources();
+ DiscardDeviceResources();
d2d_res_->GetDWriteFactory()->UnregisterFontFileLoader(res_font_file_loader_.get());
res_font_file_loader_.reset();
@@ -145,17 +142,9 @@ namespace kiwano
void Renderer::BeforeRender()
{
- HRESULT hr = S_OK;
+ KGE_ASSERT(d3d_res_ && IsValid());
- if (!IsValid())
- {
- hr = E_UNEXPECTED;
- }
-
- if (SUCCEEDED(hr))
- {
- hr = d3d_res_->ClearRenderTarget(clear_color_);
- }
+ HRESULT hr = d3d_res_->ClearRenderTarget(clear_color_);
if (SUCCEEDED(hr))
{
@@ -168,24 +157,12 @@ namespace kiwano
void Renderer::AfterRender()
{
- HRESULT hr = S_OK;
-
- if (!IsValid())
- {
- hr = E_UNEXPECTED;
- }
+ KGE_ASSERT(d3d_res_ && IsValid());
- if (SUCCEEDED(hr))
- {
- EndDraw();
+ EndDraw();
+ GetRenderTarget()->RestoreDrawingState(drawing_state_block_.get());
- GetRenderTarget()->RestoreDrawingState(drawing_state_block_.get());
- }
-
- if (SUCCEEDED(hr))
- {
- hr = d3d_res_->Present(vsync_);
- }
+ HRESULT hr = d3d_res_->Present(vsync_);
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
{
@@ -211,24 +188,20 @@ namespace kiwano
}
}
- HRESULT Renderer::CreateDeviceResources()
- {
- KGE_ASSERT(d2d_res_);
-
- HRESULT hr = RenderTarget::CreateDeviceResources(
- d2d_res_->GetDeviceContext(),
- d2d_res_
- );
- return hr;
- }
-
HRESULT Renderer::HandleDeviceLost()
{
+ KGE_ASSERT(d3d_res_ && d2d_res_ && render_target_);
+
HRESULT hr = d3d_res_->HandleDeviceLost();
if (SUCCEEDED(hr))
{
- hr = CreateDeviceResources();
+ hr = d2d_res_->HandleDeviceLost(d3d_res_->GetDXGIDevice(), d3d_res_->GetDXGISwapChain());
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = CreateDeviceResources(d2d_res_->GetFactory(), d2d_res_->GetDeviceContext());
}
return hr;
}
@@ -998,6 +971,19 @@ namespace kiwano
ThrowIfFailed(hr);
}
+ void Renderer::SetDpi(float dpi)
+ {
+ KGE_ASSERT(d3d_res_ && d2d_res_);
+
+ HRESULT hr = d3d_res_->SetDpi(dpi);
+ if (SUCCEEDED(hr))
+ {
+ hr = d2d_res_->SetDpi(dpi);
+ }
+
+ ThrowIfFailed(hr);
+ }
+
void Renderer::SetVSyncEnabled(bool enabled)
{
vsync_ = enabled;
@@ -1011,10 +997,9 @@ namespace kiwano
void Renderer::ResizeTarget(uint32_t width, uint32_t height)
{
HRESULT hr = S_OK;
+
if (!d3d_res_)
- {
hr = E_UNEXPECTED;
- }
if (SUCCEEDED(hr))
{
@@ -1023,19 +1008,17 @@ namespace kiwano
hr = d3d_res_->SetLogicalSize(output_size_);
}
+ if (SUCCEEDED(hr))
+ {
+ hr = d2d_res_->SetLogicalSize(output_size_);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ Resize(reinterpret_cast(GetRenderTarget()->GetSize()));
+ }
+
ThrowIfFailed(hr);
}
- void Renderer::Destroy()
- {
- DiscardDeviceResources();
-
- d2d_res_.reset();
- d3d_res_.reset();
- drawing_state_block_.reset();
- font_collection_loader_.reset();
- res_font_file_loader_.reset();
- res_font_collection_loader_.reset();
- }
-
}
diff --git a/src/kiwano/renderer/Renderer.h b/src/kiwano/renderer/Renderer.h
index d73155d2..2c8e6ada 100644
--- a/src/kiwano/renderer/Renderer.h
+++ b/src/kiwano/renderer/Renderer.h
@@ -171,6 +171,10 @@ namespace kiwano
GradientExtendMode extend_mode
);
+ void SetDpi(
+ float dpi
+ );
+
public:
void Init(RenderConfig const& config);
@@ -184,8 +188,6 @@ namespace kiwano
void HandleMessage(HWND hwnd, UINT32 msg, WPARAM wparam, LPARAM lparam) override;
- void Destroy();
-
public:
inline HWND GetTargetWindow() const { return hwnd_; }
@@ -202,8 +204,6 @@ namespace kiwano
~Renderer();
- HRESULT CreateDeviceResources();
-
HRESULT HandleDeviceLost();
void ResizeTarget(uint32_t width, uint32_t height);
diff --git a/src/kiwano/renderer/win32/D2DDeviceResources.cpp b/src/kiwano/renderer/win32/D2DDeviceResources.cpp
index 47c63a67..140eaca1 100644
--- a/src/kiwano/renderer/win32/D2DDeviceResources.cpp
+++ b/src/kiwano/renderer/win32/D2DDeviceResources.cpp
@@ -36,7 +36,13 @@ namespace kiwano
HRESULT CreateDeviceIndependentResources();
- public:
+ HRESULT CreateDeviceResources(
+ _In_ ComPtr dxgi_device,
+ _In_ ComPtr dxgi_swap_chain
+ );
+
+ HRESULT CreateWindowSizeDependentResources();
+
HRESULT CreateBitmapConverter(
_Out_ ComPtr& converter,
_In_opt_ ComPtr source,
@@ -65,26 +71,31 @@ namespace kiwano
HRESULT CreateTextFormat(
_Out_ ComPtr& text_format,
- _In_ String const& family,
+ String const& family,
_In_ ComPtr collection,
- _In_ DWRITE_FONT_WEIGHT weight,
- _In_ DWRITE_FONT_STYLE style,
- _In_ DWRITE_FONT_STRETCH stretch,
- _In_ FLOAT font_size
+ DWRITE_FONT_WEIGHT weight,
+ DWRITE_FONT_STYLE style,
+ DWRITE_FONT_STRETCH stretch,
+ FLOAT font_size
) override;
HRESULT CreateTextLayout(
_Out_ ComPtr& text_layout,
- _In_ String const& text,
+ String const& text,
_In_ ComPtr text_format
) override;
- HRESULT SetD2DDevice(
- _In_ ComPtr device
+ HRESULT SetDpi(
+ float dpi
) override;
- void SetTargetBitmap(
- _In_ ComPtr target
+ HRESULT SetLogicalSize(
+ Size logical_size
+ ) override;
+
+ HRESULT HandleDeviceLost(
+ _In_ ComPtr dxgi_device,
+ _In_ ComPtr dxgi_swap_chain
) override;
void DiscardResources() override;
@@ -102,10 +113,15 @@ namespace kiwano
private:
unsigned long ref_count_;
float dpi_;
+
+ ComPtr dxgi_swap_chain_;
};
- HRESULT ID2DDeviceResources::Create(ID2DDeviceResources** device_resources)
+ HRESULT ID2DDeviceResources::Create(
+ _Out_ ID2DDeviceResources** device_resources,
+ _In_ ComPtr dxgi_device,
+ _In_ ComPtr dxgi_swap_chain)
{
HRESULT hr = E_FAIL;
if (device_resources)
@@ -114,17 +130,22 @@ namespace kiwano
if (res)
{
hr = res->CreateDeviceIndependentResources();
+
+ if (SUCCEEDED(hr))
+ {
+ hr = res->CreateDeviceResources(dxgi_device, dxgi_swap_chain);
+ }
+
+ if (SUCCEEDED(hr))
+ {
+ hr = res->CreateWindowSizeDependentResources();
+ }
}
if (SUCCEEDED(hr))
{
- res->AddRef();
-
- if (*device_resources)
- {
- (*device_resources)->Release();
- }
- (*device_resources) = res;
+ DX::SafeRelease(*device_resources);
+ (*device_resources) = DX::SafeAcquire(res);
}
else
{
@@ -194,10 +215,6 @@ namespace kiwano
imaging_factory_.reset();
dwrite_factory_.reset();
-
- miter_stroke_style_.reset();
- bevel_stroke_style_.reset();
- round_stroke_style_.reset();
}
HRESULT D2DDeviceResources::CreateDeviceIndependentResources()
@@ -224,7 +241,10 @@ namespace kiwano
if (SUCCEEDED(hr))
{
factory_ = factory;
+ }
+ if (SUCCEEDED(hr))
+ {
hr = CoCreateInstance(
CLSID_WICImagingFactory,
nullptr,
@@ -232,101 +252,114 @@ namespace kiwano
__uuidof(IWICImagingFactory),
reinterpret_cast(&imaging_factory)
);
+
+ if (SUCCEEDED(hr))
+ {
+ imaging_factory_ = imaging_factory;
+ }
}
if (SUCCEEDED(hr))
{
- imaging_factory_ = imaging_factory;
-
hr = DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast(&dwrite_factory)
);
+
+ if (SUCCEEDED(hr))
+ {
+ dwrite_factory_ = dwrite_factory;
+ }
}
+ return hr;
+ }
+
+ HRESULT D2DDeviceResources::CreateDeviceResources(_In_ ComPtr dxgi_device, _In_ ComPtr dxgi_swap_chain)
+ {
+ if (!factory_)
+ return E_UNEXPECTED;
+
+ // Create the Direct2D device object and a corresponding context.
+ ComPtr device;
+ HRESULT hr = factory_->CreateDevice(dxgi_device.get(), &device);
if (SUCCEEDED(hr))
{
- dwrite_factory_ = dwrite_factory;
+ ComPtr device_ctx;
- ComPtr miter_stroke_style;
- ComPtr bevel_stroke_style;
- ComPtr round_stroke_style;
-
- D2D1_STROKE_STYLE_PROPERTIES stroke_style = D2D1::StrokeStyleProperties(
- D2D1_CAP_STYLE_FLAT,
- D2D1_CAP_STYLE_FLAT,
- D2D1_CAP_STYLE_FLAT,
- D2D1_LINE_JOIN_MITER,
- 2.0f,
- D2D1_DASH_STYLE_SOLID,
- 0.0f
- );
-
- hr = factory_->CreateStrokeStyle(
- stroke_style,
- nullptr,
- 0,
- &miter_stroke_style
+ hr = device->CreateDeviceContext(
+ D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
+ &device_ctx
);
if (SUCCEEDED(hr))
{
- stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL;
- hr = factory_->CreateStrokeStyle(
- stroke_style,
- nullptr,
- 0,
- &bevel_stroke_style
- );
- }
-
- if (SUCCEEDED(hr))
- {
- stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND;
- hr = factory_->CreateStrokeStyle(
- stroke_style,
- nullptr,
- 0,
- &round_stroke_style
- );
- }
-
- if (SUCCEEDED(hr))
- {
- miter_stroke_style_ = miter_stroke_style;
- bevel_stroke_style_ = bevel_stroke_style;
- round_stroke_style_ = round_stroke_style;
+ device_ = device;
+ device_context_ = device_ctx;
+ device_context_->SetDpi(dpi_, dpi_);
+ dxgi_swap_chain_ = dxgi_swap_chain;
}
}
-
return hr;
}
- HRESULT D2DDeviceResources::SetD2DDevice(_In_ ComPtr device)
+ HRESULT D2DDeviceResources::CreateWindowSizeDependentResources()
{
- ComPtr device_ctx;
+ if (!dxgi_swap_chain_ || !device_context_)
+ return E_UNEXPECTED;
- HRESULT hr = device->CreateDeviceContext(
- D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
- &device_ctx
- );
+ // Create a Direct2D target bitmap associated with the
+ // swap chain back buffer and set it as the current target.
+ ComPtr dxgi_back_buffer;
+ HRESULT hr = dxgi_swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dxgi_back_buffer));
if (SUCCEEDED(hr))
{
- device_ = device;
- device_context_ = device_ctx;
- device_context_->SetDpi(dpi_, dpi_);
- }
+ ComPtr target;
+ hr = device_context_->CreateBitmapFromDxgiSurface(
+ dxgi_back_buffer.get(),
+ D2D1::BitmapProperties1(
+ D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
+ D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
+ dpi_,
+ dpi_),
+ &target);
- return hr;
+ if (SUCCEEDED(hr))
+ {
+ target_bitmap_ = target;
+ device_context_->SetTarget(target_bitmap_.get());
+ }
+ }
+ return E_NOTIMPL;
}
- void D2DDeviceResources::SetTargetBitmap(_In_ ComPtr target)
+ HRESULT D2DDeviceResources::SetDpi(float dpi)
{
- target_bitmap_ = target;
- if (device_context_)
- device_context_->SetTarget(target_bitmap_.get());
+ if (!device_context_)
+ return E_UNEXPECTED;
+
+ device_context_->SetDpi(dpi, dpi);
+ return CreateWindowSizeDependentResources();
+ }
+
+ HRESULT D2DDeviceResources::SetLogicalSize(Size)
+ {
+ return CreateWindowSizeDependentResources();
+ }
+
+ HRESULT D2DDeviceResources::HandleDeviceLost(_In_ ComPtr dxgi_device, _In_ ComPtr dxgi_swap_chain)
+ {
+ dxgi_swap_chain_ = nullptr;
+
+ HRESULT hr = CreateDeviceResources(dxgi_device, dxgi_swap_chain);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = CreateWindowSizeDependentResources();
+ }
+ return hr;
}
HRESULT D2DDeviceResources::CreateBitmapConverter(_Out_ ComPtr& converter, _In_opt_ ComPtr source,
@@ -440,8 +473,8 @@ namespace kiwano
return hr;
}
- HRESULT D2DDeviceResources::CreateTextFormat(_Out_ ComPtr & text_format, _In_ String const& family, _In_ ComPtr collection,
- _In_ DWRITE_FONT_WEIGHT weight, _In_ DWRITE_FONT_STYLE style, _In_ DWRITE_FONT_STRETCH stretch, _In_ FLOAT font_size)
+ HRESULT D2DDeviceResources::CreateTextFormat(_Out_ ComPtr & text_format, String const& family, _In_ ComPtr collection,
+ DWRITE_FONT_WEIGHT weight, DWRITE_FONT_STYLE style, DWRITE_FONT_STRETCH stretch, FLOAT font_size)
{
if (!dwrite_factory_)
return E_UNEXPECTED;
@@ -465,7 +498,7 @@ namespace kiwano
return hr;
}
- HRESULT D2DDeviceResources::CreateTextLayout(_Out_ ComPtr& text_layout, _In_ String const& text,
+ HRESULT D2DDeviceResources::CreateTextLayout(_Out_ ComPtr& text_layout, String const& text,
_In_ ComPtr text_format)
{
if (!dwrite_factory_)
diff --git a/src/kiwano/renderer/win32/D2DDeviceResources.h b/src/kiwano/renderer/win32/D2DDeviceResources.h
index 04565b8b..b9f9a943 100644
--- a/src/kiwano/renderer/win32/D2DDeviceResources.h
+++ b/src/kiwano/renderer/win32/D2DDeviceResources.h
@@ -19,166 +19,12 @@
// THE SOFTWARE.
#pragma once
-#include
#include
-#include
-#include
+#include
#include
#include
#include
-namespace kiwano
-{
- namespace DX
- {
- template
- inline void SafeRelease(T*& ptr)
- {
- if (ptr != nullptr)
- {
- ptr->Release();
- ptr = nullptr;
- }
- }
-
- template
- inline T* SafeAcquire(T* ptr)
- {
- if (ptr != nullptr)
- {
- ptr->AddRef();
- }
- return ptr;
- }
-
- //
- // Point2F
- //
-
- inline D2D1_POINT_2F const& ConvertToPoint2F(Vec2 const& vec2)
- {
- return reinterpret_cast(vec2);
- }
-
- inline D2D1_POINT_2F& ConvertToPoint2F(Vec2& vec2)
- {
- return reinterpret_cast(vec2);
- }
-
- inline const D2D1_POINT_2F* ConvertToPoint2F(const Vec2* vec2)
- {
- return reinterpret_cast(vec2);
- }
-
- inline D2D1_POINT_2F* ConvertToPoint2F(Vec2* vec2)
- {
- return reinterpret_cast(vec2);
- }
-
- //
- // SizeF
- //
-
- inline D2D1_SIZE_F const& ConvertToSizeF(Vec2 const& vec2)
- {
- return reinterpret_cast(vec2);
- }
-
- inline D2D1_SIZE_F& ConvertToSizeF(Vec2& vec2)
- {
- return reinterpret_cast(vec2);
- }
-
- inline const D2D1_SIZE_F* ConvertToSizeF(const Vec2* vec2)
- {
- return reinterpret_cast(vec2);
- }
-
- inline D2D1_SIZE_F* ConvertToSizeF(Vec2* vec2)
- {
- return reinterpret_cast(vec2);
- }
-
- //
- // RectF
- //
-
- inline D2D1_RECT_F const& ConvertToRectF(Rect const& rect)
- {
- return reinterpret_cast(rect);
- }
-
- inline D2D1_RECT_F& ConvertToRectF(Rect& rect)
- {
- return reinterpret_cast(rect);
- }
-
- inline const D2D1_RECT_F* ConvertToRectF(const Rect* rect)
- {
- return reinterpret_cast(rect);
- }
-
- inline D2D1_RECT_F* ConvertToRectF(Rect* rect)
- {
- return reinterpret_cast(rect);
- }
-
- //
- // ColorF
- //
- inline D2D1_COLOR_F const& ConvertToColorF(Color const& color)
- {
- return reinterpret_cast(color);
- }
-
- inline D2D1_COLOR_F& ConvertToColorF(Color& color)
- {
- return reinterpret_cast(color);
- }
-
- inline const D2D1_COLOR_F* ConvertToColorF(const Color* color)
- {
- return reinterpret_cast(color);
- }
-
- inline D2D1_COLOR_F* ConvertToColorF(Color* color)
- {
- return reinterpret_cast(color);
- }
-
- //
- // MatrixF
- //
-
- inline D2D1_MATRIX_3X2_F const& ConvertToMatrix3x2F(Matrix3x2 const& matrix)
- {
- return reinterpret_cast(matrix);
- }
-
- inline D2D1_MATRIX_3X2_F& ConvertToMatrix3x2F(Matrix3x2& matrix)
- {
- return reinterpret_cast(matrix);
- }
-
- inline const D2D1_MATRIX_3X2_F* ConvertToMatrix3x2F(const Matrix3x2* matrix)
- {
- return reinterpret_cast(matrix);
- }
-
- inline D2D1_MATRIX_3X2_F* ConvertToMatrix3x2F(Matrix3x2* matrix)
- {
- return reinterpret_cast(matrix);
- }
-
- // Converts a length in device-independent pixels (DIPs) to a length in physical pixels.
- inline float ConvertDipsToPixels(float dips, float dpi)
- {
- static const float dips_per_inch = 96.0f;
- return math::Floor(dips * dpi / dips_per_inch + 0.5f); // Round to nearest integer.
- }
- }
-}
-
namespace kiwano
{
MIDL_INTERFACE("5706684a-bf6d-4b03-b627-094758a33032")
@@ -186,7 +32,11 @@ namespace kiwano
: public IUnknown
{
public:
- static HRESULT Create(ID2DDeviceResources** device_resources);
+ static HRESULT Create(
+ _Out_ ID2DDeviceResources** device_resources,
+ _In_ ComPtr dxgi_device,
+ _In_ ComPtr dxgi_swap_chain
+ );
virtual HRESULT CreateBitmapConverter(
_Out_ ComPtr& converter,
@@ -216,26 +66,31 @@ namespace kiwano
virtual HRESULT CreateTextFormat(
_Out_ ComPtr& text_format,
- _In_ String const& family,
+ String const& family,
_In_ ComPtr collection,
- _In_ DWRITE_FONT_WEIGHT weight,
- _In_ DWRITE_FONT_STYLE style,
- _In_ DWRITE_FONT_STRETCH stretch,
- _In_ FLOAT font_size
+ DWRITE_FONT_WEIGHT weight,
+ DWRITE_FONT_STYLE style,
+ DWRITE_FONT_STRETCH stretch,
+ FLOAT font_size
) = 0;
virtual HRESULT CreateTextLayout(
_Out_ ComPtr& text_layout,
- _In_ String const& text,
+ String const& text,
_In_ ComPtr text_format
) = 0;
- virtual HRESULT SetD2DDevice(
- _In_ ComPtr device
+ virtual HRESULT SetDpi(
+ float dpi
) = 0;
- virtual void SetTargetBitmap(
- _In_ ComPtr target
+ virtual HRESULT SetLogicalSize(
+ Size logical_size
+ ) = 0;
+
+ virtual HRESULT HandleDeviceLost(
+ _In_ ComPtr dxgi_device,
+ _In_ ComPtr dxgi_swap_chain
) = 0;
virtual void DiscardResources() = 0;
@@ -247,10 +102,6 @@ namespace kiwano
inline ID2D1DeviceContext* GetDeviceContext() { KGE_ASSERT(device_context_); return device_context_.get(); }
inline ID2D1Bitmap1* GetTargetBitmap() { KGE_ASSERT(target_bitmap_); return target_bitmap_.get(); }
- inline ID2D1StrokeStyle* GetMiterStrokeStyle() { KGE_ASSERT(miter_stroke_style_); return miter_stroke_style_.get(); }
- inline ID2D1StrokeStyle* GetBevelStrokeStyle() { KGE_ASSERT(bevel_stroke_style_); return bevel_stroke_style_.get(); }
- inline ID2D1StrokeStyle* GetRoundStrokeStyle() { KGE_ASSERT(round_stroke_style_); return round_stroke_style_.get(); }
-
protected:
ComPtr factory_;
ComPtr device_;
@@ -259,10 +110,6 @@ namespace kiwano
ComPtr imaging_factory_;
ComPtr dwrite_factory_;
-
- ComPtr miter_stroke_style_;
- ComPtr bevel_stroke_style_;
- ComPtr round_stroke_style_;
};
}
diff --git a/src/kiwano/renderer/win32/D3D10DeviceResources.cpp b/src/kiwano/renderer/win32/D3D10DeviceResources.cpp
index 274618ec..72ad2574 100644
--- a/src/kiwano/renderer/win32/D3D10DeviceResources.cpp
+++ b/src/kiwano/renderer/win32/D3D10DeviceResources.cpp
@@ -118,8 +118,6 @@ namespace kiwano
Size logical_size_;
Size output_size_;
unsigned long ref_count_;
-
- ComPtr d2d_res_;
};
@@ -135,11 +133,11 @@ namespace kiwano
DiscardResources();
}
- HRESULT ID3D10DeviceResources::Create(ID3D10DeviceResources** device_resources, ID2DDeviceResources* d2d_device_res, HWND hwnd)
+ HRESULT ID3D10DeviceResources::Create(ID3D10DeviceResources** device_resources, HWND hwnd)
{
HRESULT hr = E_FAIL;
- if (device_resources && d2d_device_res)
+ if (device_resources)
{
D3D10DeviceResources* res = new (std::nothrow) D3D10DeviceResources;
if (res)
@@ -148,7 +146,6 @@ namespace kiwano
::GetClientRect(hwnd, &rc);
res->hwnd_ = hwnd;
- res->d2d_res_ = d2d_device_res;
res->logical_size_.x = float(rc.right - rc.left);
res->logical_size_.y = float(rc.bottom - rc.top);
@@ -199,10 +196,10 @@ namespace kiwano
void D3D10DeviceResources::DiscardResources()
{
- d2d_res_.reset();
device_.reset();
rt_view_.reset();
ds_view_.reset();
+ dxgi_device_.reset();
dxgi_swap_chain_.reset();
dxgi_factory_.reset();
@@ -236,40 +233,29 @@ namespace kiwano
{
device_ = device;
- ComPtr dxgi_adapter;
- ComPtr dxgi_device;
- ComPtr dxgi_factory;
- ComPtr d2d_device;
-
if (SUCCEEDED(hr))
{
+ ComPtr dxgi_device;
hr = device_->QueryInterface(IID_PPV_ARGS(&dxgi_device));
- }
- if (SUCCEEDED(hr))
- {
- hr = dxgi_device->GetAdapter(&dxgi_adapter);
- }
+ if (SUCCEEDED(hr))
+ {
+ dxgi_device_ = dxgi_device;
- if (SUCCEEDED(hr))
- {
- hr = dxgi_adapter->GetParent(IID_PPV_ARGS(&dxgi_factory));
- }
+ ComPtr dxgi_adapter;
+ hr = dxgi_device_->GetAdapter(&dxgi_adapter);
- if (SUCCEEDED(hr))
- {
- dxgi_factory_ = dxgi_factory;
- }
+ if (SUCCEEDED(hr))
+ {
+ ComPtr dxgi_factory;
+ hr = dxgi_adapter->GetParent(IID_PPV_ARGS(&dxgi_factory));
- // Create the Direct2D device object and a corresponding context.
- if (SUCCEEDED(hr))
- {
- hr = d2d_res_->GetFactory()->CreateDevice(dxgi_device.get(), &d2d_device);
- }
-
- if (SUCCEEDED(hr))
- {
- hr = d2d_res_->SetD2DDevice(d2d_device);
+ if (SUCCEEDED(hr))
+ {
+ dxgi_factory_ = dxgi_factory;
+ }
+ }
+ }
}
}
@@ -292,31 +278,11 @@ namespace kiwano
swap_chain_desc.Windowed = TRUE;
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
- ComPtr dxgi_device;
- if (SUCCEEDED(hr))
- {
- hr = device_->QueryInterface(&dxgi_device);
- }
-
- ComPtr dxgi_adapter;
- if (SUCCEEDED(hr))
- {
- hr = dxgi_device->GetAdapter(&dxgi_adapter);
- }
-
- ComPtr dxgi_factory;
- if (SUCCEEDED(hr))
- {
- hr = dxgi_adapter->GetParent(IID_PPV_ARGS(&dxgi_factory));
- }
-
- if (SUCCEEDED(hr))
- {
- hr = dxgi_factory->CreateSwapChain(
- device_.get(),
- &swap_chain_desc,
- &dxgi_swap_chain_);
- }
+ hr = dxgi_factory_->CreateSwapChain(
+ device_.get(),
+ &swap_chain_desc,
+ &dxgi_swap_chain_
+ );
}
return hr;
@@ -332,7 +298,6 @@ namespace kiwano
// Clear the previous window size specific context.
ID3D10RenderTargetView* null_views[] = { nullptr };
device_->OMSetRenderTargets(ARRAYSIZE(null_views), null_views, nullptr);
- d2d_res_->SetTargetBitmap(nullptr);
rt_view_ = nullptr;
ds_view_ = nullptr;
device_->Flush();
@@ -424,33 +389,6 @@ namespace kiwano
device_->RSSetViewports(1, &viewport);
}
-
- // Create a Direct2D target bitmap associated with the
- // swap chain back buffer and set it as the current target.
- if (SUCCEEDED(hr))
- {
- ComPtr dxgi_back_buffer;
- hr = dxgi_swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dxgi_back_buffer));
-
- ComPtr target;
- if (SUCCEEDED(hr))
- {
- hr = d2d_res_->GetDeviceContext()->CreateBitmapFromDxgiSurface(
- dxgi_back_buffer.get(),
- D2D1::BitmapProperties1(
- D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
- D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
- dpi_,
- dpi_),
- &target);
- }
-
- if (SUCCEEDED(hr))
- {
- d2d_res_->SetTargetBitmap(target);
- }
- }
-
return hr;
}
@@ -490,8 +428,6 @@ namespace kiwano
logical_size_.x = float(rc.right - rc.left);
logical_size_.y = float(rc.bottom - rc.top);
- d2d_res_->GetDeviceContext()->SetDpi(dpi_, dpi_);
-
return CreateWindowSizeDependentResources();
}
return S_OK;
diff --git a/src/kiwano/renderer/win32/D3D10DeviceResources.h b/src/kiwano/renderer/win32/D3D10DeviceResources.h
index 1d72688c..40e3f6dc 100644
--- a/src/kiwano/renderer/win32/D3D10DeviceResources.h
+++ b/src/kiwano/renderer/win32/D3D10DeviceResources.h
@@ -21,8 +21,7 @@
#pragma once
#include
-
-#include
+#include
#include
#include
@@ -33,20 +32,22 @@ namespace kiwano
: public ID3DDeviceResourcesBase
{
public:
- static HRESULT Create(ID3D10DeviceResources** device_resources, ID2DDeviceResources* d2d_device_res, HWND hwnd);
+ static HRESULT Create(ID3D10DeviceResources** device_resources, HWND hwnd);
inline ID3D10Device* GetDevice() { KGE_ASSERT(device_); return device_.get(); }
inline ID3D10RenderTargetView* GetRenderTargetView() { KGE_ASSERT(rt_view_); return rt_view_.get(); }
inline ID3D10DepthStencilView* GetDepthStencilView() { KGE_ASSERT(ds_view_); return ds_view_.get(); }
inline IDXGIFactory* GetDXGIFactory() { KGE_ASSERT(dxgi_factory_); return dxgi_factory_.get(); }
+ inline IDXGIDevice* GetDXGIDevice() { KGE_ASSERT(dxgi_device_); return dxgi_device_.get(); }
inline IDXGISwapChain* GetDXGISwapChain() { KGE_ASSERT(dxgi_swap_chain_); return dxgi_swap_chain_.get(); }
protected:
ComPtr device_;
ComPtr rt_view_;
ComPtr ds_view_;
- ComPtr dxgi_swap_chain_;
ComPtr dxgi_factory_;
+ ComPtr dxgi_device_;
+ ComPtr dxgi_swap_chain_;
};
}
diff --git a/src/kiwano/renderer/win32/D3D11DeviceResources.cpp b/src/kiwano/renderer/win32/D3D11DeviceResources.cpp
index b6ebbd6c..5145978c 100644
--- a/src/kiwano/renderer/win32/D3D11DeviceResources.cpp
+++ b/src/kiwano/renderer/win32/D3D11DeviceResources.cpp
@@ -19,8 +19,8 @@
// THE SOFTWARE.
#include
-
#include
+
#include // IsWindows10OrGreater
#pragma comment(lib, "d3d11.lib")
@@ -95,7 +95,6 @@ namespace kiwano
unsigned long ref_count_;
D3D_FEATURE_LEVEL d3d_feature_level_;
- ComPtr d2d_res_;
};
@@ -112,11 +111,11 @@ namespace kiwano
DiscardResources();
}
- HRESULT ID3D11DeviceResources::Create(ID3D11DeviceResources** device_resources, ID2DDeviceResources* d2d_device_res, HWND hwnd)
+ HRESULT ID3D11DeviceResources::Create(ID3D11DeviceResources** device_resources, HWND hwnd)
{
HRESULT hr = E_FAIL;
- if (device_resources && d2d_device_res)
+ if (device_resources)
{
D3D11DeviceResources* res = new (std::nothrow) D3D11DeviceResources;
if (res)
@@ -125,7 +124,6 @@ namespace kiwano
::GetClientRect(hwnd, &rc);
res->hwnd_ = hwnd;
- res->d2d_res_ = d2d_device_res;
res->logical_size_.x = float(rc.right - rc.left);
res->logical_size_.y = float(rc.bottom - rc.top);
@@ -176,11 +174,11 @@ namespace kiwano
void D3D11DeviceResources::DiscardResources()
{
- d2d_res_.reset();
device_.reset();
device_context_.reset();
rt_view_.reset();
ds_view_.reset();
+ dxgi_device_.reset();
dxgi_swap_chain_.reset();
dxgi_factory_.reset();
@@ -253,40 +251,29 @@ namespace kiwano
device_ = device;
device_context_ = context;
- ComPtr dxgi_adapter;
- ComPtr dxgi_device;
- ComPtr dxgi_factory;
- ComPtr d2d_device;
-
if (SUCCEEDED(hr))
{
+ ComPtr dxgi_device;
hr = device_->QueryInterface(IID_PPV_ARGS(&dxgi_device));
- }
- if (SUCCEEDED(hr))
- {
- hr = dxgi_device->GetAdapter(&dxgi_adapter);
- }
+ if (SUCCEEDED(hr))
+ {
+ dxgi_device_ = dxgi_device;
- if (SUCCEEDED(hr))
- {
- hr = dxgi_adapter->GetParent(IID_PPV_ARGS(&dxgi_factory));
- }
+ ComPtr dxgi_adapter;
+ hr = dxgi_device_->GetAdapter(&dxgi_adapter);
- if (SUCCEEDED(hr))
- {
- dxgi_factory_ = dxgi_factory;
- }
+ if (SUCCEEDED(hr))
+ {
+ ComPtr dxgi_factory;
+ hr = dxgi_adapter->GetParent(IID_PPV_ARGS(&dxgi_factory));
- // Create the Direct2D device object and a corresponding context.
- if (SUCCEEDED(hr))
- {
- hr = d2d_res_->GetFactory()->CreateDevice(dxgi_device.get(), &d2d_device);
- }
-
- if (SUCCEEDED(hr))
- {
- hr = d2d_res_->SetD2DDevice(d2d_device);
+ if (SUCCEEDED(hr))
+ {
+ dxgi_factory_ = dxgi_factory;
+ }
+ }
+ }
}
}
@@ -328,33 +315,12 @@ namespace kiwano
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
}
- ComPtr dxgi_device;
- if (SUCCEEDED(hr))
- {
- hr = device_->QueryInterface(&dxgi_device);
- }
-
- ComPtr dxgi_adapter;
- if (SUCCEEDED(hr))
- {
- hr = dxgi_device->GetAdapter(&dxgi_adapter);
- }
-
- ComPtr dxgi_factory;
- if (SUCCEEDED(hr))
- {
- hr = dxgi_adapter->GetParent(IID_PPV_ARGS(&dxgi_factory));
- }
-
- if (SUCCEEDED(hr))
- {
- hr = dxgi_factory->CreateSwapChain(
- device_.get(),
- &swap_chain_desc,
- &dxgi_swap_chain_);
- }
+ hr = dxgi_factory_->CreateSwapChain(
+ device_.get(),
+ &swap_chain_desc,
+ &dxgi_swap_chain_
+ );
}
-
return hr;
}
@@ -368,7 +334,6 @@ namespace kiwano
// Clear the previous window size specific context.
ID3D11RenderTargetView* null_views[] = { nullptr };
device_context_->OMSetRenderTargets(ARRAYSIZE(null_views), null_views, nullptr);
- d2d_res_->SetTargetBitmap(nullptr);
rt_view_ = nullptr;
ds_view_ = nullptr;
device_context_->Flush();
@@ -444,32 +409,6 @@ namespace kiwano
device_context_->RSSetViewports(1, &screen_viewport);
}
- // Create a Direct2D target bitmap associated with the
- // swap chain back buffer and set it as the current target.
- if (SUCCEEDED(hr))
- {
- ComPtr dxgi_back_buffer;
- hr = dxgi_swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dxgi_back_buffer));
-
- ComPtr target;
- if (SUCCEEDED(hr))
- {
- hr = d2d_res_->GetDeviceContext()->CreateBitmapFromDxgiSurface(
- dxgi_back_buffer.get(),
- D2D1::BitmapProperties1(
- D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
- D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
- dpi_,
- dpi_),
- &target);
- }
-
- if (SUCCEEDED(hr))
- {
- d2d_res_->SetTargetBitmap(target);
- }
- }
-
return hr;
}
@@ -509,8 +448,6 @@ namespace kiwano
logical_size_.x = float(rc.right - rc.left);
logical_size_.y = float(rc.bottom - rc.top);
- d2d_res_->GetDeviceContext()->SetDpi(dpi_, dpi_);
-
return CreateWindowSizeDependentResources();
}
return S_OK;
diff --git a/src/kiwano/renderer/win32/D3D11DeviceResources.h b/src/kiwano/renderer/win32/D3D11DeviceResources.h
index a7b9d65a..c10cb1e0 100644
--- a/src/kiwano/renderer/win32/D3D11DeviceResources.h
+++ b/src/kiwano/renderer/win32/D3D11DeviceResources.h
@@ -21,8 +21,7 @@
#pragma once
#include
-
-#include
+#include
#include
#include
@@ -33,13 +32,14 @@ namespace kiwano
: public ID3DDeviceResourcesBase
{
public:
- static HRESULT Create(ID3D11DeviceResources** device_resources, ID2DDeviceResources* d2d_device_res, HWND hwnd);
+ static HRESULT Create(ID3D11DeviceResources** device_resources, HWND hwnd);
inline ID3D11Device* GetDevice() { KGE_ASSERT(device_); return device_.get(); }
inline ID3D11DeviceContext* GetDeviceContext() { KGE_ASSERT(device_context_); return device_context_.get(); }
inline ID3D11RenderTargetView* GetRenderTargetView() { KGE_ASSERT(rt_view_); return rt_view_.get(); }
inline ID3D11DepthStencilView* GetDepthStencilView() { KGE_ASSERT(ds_view_); return ds_view_.get(); }
inline IDXGIFactory* GetDXGIFactory() { KGE_ASSERT(dxgi_factory_); return dxgi_factory_.get(); }
+ inline IDXGIDevice* GetDXGIDevice() { KGE_ASSERT(dxgi_device_); return dxgi_device_.get(); }
inline IDXGISwapChain* GetDXGISwapChain() { KGE_ASSERT(dxgi_swap_chain_); return dxgi_swap_chain_.get(); }
protected:
@@ -47,8 +47,9 @@ namespace kiwano
ComPtr device_context_;
ComPtr rt_view_;
ComPtr ds_view_;
- ComPtr dxgi_swap_chain_;
ComPtr dxgi_factory_;
+ ComPtr dxgi_device_;
+ ComPtr dxgi_swap_chain_;
};
}
diff --git a/src/kiwano/renderer/win32/helper.h b/src/kiwano/renderer/win32/helper.h
new file mode 100644
index 00000000..ff1c22ed
--- /dev/null
+++ b/src/kiwano/renderer/win32/helper.h
@@ -0,0 +1,177 @@
+// 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
+#include
+
+namespace kiwano
+{
+ namespace DX
+ {
+ template
+ inline void SafeRelease(T*& ptr)
+ {
+ if (ptr != nullptr)
+ {
+ ptr->Release();
+ ptr = nullptr;
+ }
+ }
+
+ template
+ inline T* SafeAcquire(T* ptr)
+ {
+ if (ptr != nullptr)
+ {
+ ptr->AddRef();
+ }
+ return ptr;
+ }
+
+ //
+ // Point2F
+ //
+
+ inline D2D1_POINT_2F const& ConvertToPoint2F(Vec2 const& vec2)
+ {
+ return reinterpret_cast(vec2);
+ }
+
+ inline D2D1_POINT_2F& ConvertToPoint2F(Vec2& vec2)
+ {
+ return reinterpret_cast(vec2);
+ }
+
+ inline const D2D1_POINT_2F* ConvertToPoint2F(const Vec2* vec2)
+ {
+ return reinterpret_cast(vec2);
+ }
+
+ inline D2D1_POINT_2F* ConvertToPoint2F(Vec2* vec2)
+ {
+ return reinterpret_cast(vec2);
+ }
+
+ //
+ // SizeF
+ //
+
+ inline D2D1_SIZE_F const& ConvertToSizeF(Vec2 const& vec2)
+ {
+ return reinterpret_cast(vec2);
+ }
+
+ inline D2D1_SIZE_F& ConvertToSizeF(Vec2& vec2)
+ {
+ return reinterpret_cast(vec2);
+ }
+
+ inline const D2D1_SIZE_F* ConvertToSizeF(const Vec2* vec2)
+ {
+ return reinterpret_cast(vec2);
+ }
+
+ inline D2D1_SIZE_F* ConvertToSizeF(Vec2* vec2)
+ {
+ return reinterpret_cast(vec2);
+ }
+
+ //
+ // RectF
+ //
+
+ inline D2D1_RECT_F const& ConvertToRectF(Rect const& rect)
+ {
+ return reinterpret_cast(rect);
+ }
+
+ inline D2D1_RECT_F& ConvertToRectF(Rect& rect)
+ {
+ return reinterpret_cast(rect);
+ }
+
+ inline const D2D1_RECT_F* ConvertToRectF(const Rect* rect)
+ {
+ return reinterpret_cast(rect);
+ }
+
+ inline D2D1_RECT_F* ConvertToRectF(Rect* rect)
+ {
+ return reinterpret_cast(rect);
+ }
+
+ //
+ // ColorF
+ //
+ inline D2D1_COLOR_F const& ConvertToColorF(Color const& color)
+ {
+ return reinterpret_cast(color);
+ }
+
+ inline D2D1_COLOR_F& ConvertToColorF(Color& color)
+ {
+ return reinterpret_cast(color);
+ }
+
+ inline const D2D1_COLOR_F* ConvertToColorF(const Color* color)
+ {
+ return reinterpret_cast(color);
+ }
+
+ inline D2D1_COLOR_F* ConvertToColorF(Color* color)
+ {
+ return reinterpret_cast(color);
+ }
+
+ //
+ // MatrixF
+ //
+
+ inline D2D1_MATRIX_3X2_F const& ConvertToMatrix3x2F(Matrix3x2 const& matrix)
+ {
+ return reinterpret_cast(matrix);
+ }
+
+ inline D2D1_MATRIX_3X2_F& ConvertToMatrix3x2F(Matrix3x2& matrix)
+ {
+ return reinterpret_cast(matrix);
+ }
+
+ inline const D2D1_MATRIX_3X2_F* ConvertToMatrix3x2F(const Matrix3x2* matrix)
+ {
+ return reinterpret_cast(matrix);
+ }
+
+ inline D2D1_MATRIX_3X2_F* ConvertToMatrix3x2F(Matrix3x2* matrix)
+ {
+ return reinterpret_cast(matrix);
+ }
+
+ // Converts a length in device-independent pixels (DIPs) to a length in physical pixels.
+ inline float ConvertDipsToPixels(float dips, float dpi)
+ {
+ static const float dips_per_inch = 96.0f;
+ return math::Floor(dips * dpi / dips_per_inch + 0.5f); // Round to nearest integer.
+ }
+ }
+}