Update RenderTarget & Renderer
This commit is contained in:
parent
ef77e76c6c
commit
c50755bb4b
|
|
@ -75,6 +75,7 @@
|
|||
<ClInclude Include="..\..\src\kiwano\renderer\win32\D3D11DeviceResources.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\win32\D3DDeviceResourcesBase.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\win32\FontCollectionLoader.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\win32\helper.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\win32\TextRenderer.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\ui\Button.h" />
|
||||
<ClInclude Include="..\..\src\kiwano\ui\Menu.h" />
|
||||
|
|
|
|||
|
|
@ -267,6 +267,9 @@
|
|||
<ClInclude Include="..\..\src\kiwano\renderer\TextStyle.hpp">
|
||||
<Filter>renderer</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\kiwano\renderer\win32\helper.h">
|
||||
<Filter>renderer\win32</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\kiwano\ui\Button.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)
|
||||
|
|
|
|||
|
|
@ -18,18 +18,16 @@
|
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include <kiwano/core/Logger.h>
|
||||
#include <stdexcept>
|
||||
#include <kiwano/macros.h>
|
||||
#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];
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <kiwano/platform/Application.h>
|
||||
#include <kiwano/platform/modules.h>
|
||||
#include <kiwano/core/Logger.h>
|
||||
#include <kiwano/core/win32/helper.h>
|
||||
#include <kiwano/platform/Input.h>
|
||||
#include <kiwano/platform/Director.h>
|
||||
|
|
@ -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<int>(wparam);
|
||||
// evt.count = static_cast<int>(lparam & 0xFF);
|
||||
app->DispatchEvent(evt);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyUpEvent evt;
|
||||
evt.code = static_cast<int>(wparam);
|
||||
// evt.count = static_cast<int>(lparam & 0xFF);
|
||||
app->DispatchEvent(evt);
|
||||
}
|
||||
}
|
||||
|
|
@ -321,7 +318,6 @@ namespace kiwano
|
|||
{
|
||||
KeyCharEvent evt;
|
||||
evt.value = static_cast<char>(wparam);
|
||||
// evt.count = static_cast<int>(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<const wchar_t*>(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())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -140,8 +140,4 @@ namespace kiwano
|
|||
{
|
||||
return Point{ mouse_pos_x_, mouse_pos_y_ };
|
||||
}
|
||||
|
||||
void Input::Destroy()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,8 +100,6 @@ namespace kiwano
|
|||
|
||||
void UpdateMousePos(float, float);
|
||||
|
||||
void Destroy();
|
||||
|
||||
private:
|
||||
Input();
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <kiwano/platform/Window.h>
|
||||
#include <kiwano/core/win32/helper.h>
|
||||
#include <kiwano/core/Logger.h>
|
||||
#include <kiwano/platform/Application.h>
|
||||
|
||||
#define WINDOW_FIXED_STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <kiwano/renderer/RenderTarget.h>
|
||||
#include <kiwano/core/win32/helper.h>
|
||||
#include <kiwano/core/Logger.h>
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
|
|
@ -36,32 +37,64 @@ namespace kiwano
|
|||
status_.primitives = 0;
|
||||
}
|
||||
|
||||
HRESULT RenderTarget::CreateDeviceResources(ComPtr<ID2D1RenderTarget> rt, ComPtr<ID2DDeviceResources> dev_res)
|
||||
HRESULT RenderTarget::CreateDeviceResources(ComPtr<ID2D1Factory> factory, ComPtr<ID2D1RenderTarget> 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<const Size&>(GetRenderTarget()->GetSize()));
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ComPtr<ID2D1StrokeStyle> miter_stroke_style;
|
||||
ComPtr<ID2D1StrokeStyle> bevel_stroke_style;
|
||||
ComPtr<ID2D1StrokeStyle> 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<uint32_t> 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<ID2D1Bitmap> saved_bitmap;
|
||||
HRESULT hr = render_target_->CreateBitmap(
|
||||
D2D1::SizeU(size.x, size.y),
|
||||
D2D1::BitmapProperties(format),
|
||||
&saved_bitmap
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ComPtr<ID2D1Bitmap> 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<ID2D1Layer> 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<ID2D1StrokeStyle> 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<const Size&>(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)
|
||||
|
|
|
|||
|
|
@ -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<ID2D1RenderTarget> GetRenderTarget() const { KGE_ASSERT(render_target_); return render_target_; }
|
||||
|
||||
inline ComPtr<ITextRenderer> GetTextRenderer() const { KGE_ASSERT(text_renderer_); return text_renderer_; }
|
||||
|
||||
ComPtr<ID2D1StrokeStyle> GetStrokeStyle(StrokeStyle style);
|
||||
|
||||
protected:
|
||||
RenderTarget();
|
||||
|
||||
HRESULT CreateDeviceResources(ComPtr<ID2D1RenderTarget> rt, ComPtr<ID2DDeviceResources> dev_res);
|
||||
private:
|
||||
HRESULT CreateDeviceResources(ComPtr<ID2D1Factory> factory, ComPtr<ID2D1RenderTarget> rt);
|
||||
|
||||
void DiscardDeviceResources();
|
||||
|
||||
private:
|
||||
bool antialias_;
|
||||
bool fast_global_transform_;
|
||||
mutable bool collecting_status_;
|
||||
mutable Status status_;
|
||||
TextAntialiasMode text_antialias_;
|
||||
ComPtr<ITextRenderer> text_renderer_;
|
||||
ComPtr<ID2D1RenderTarget> render_target_;
|
||||
ComPtr<ID2DDeviceResources> device_resources_;
|
||||
ComPtr<ID2D1StrokeStyle> miter_stroke_style_;
|
||||
ComPtr<ID2D1StrokeStyle> bevel_stroke_style_;
|
||||
ComPtr<ID2D1StrokeStyle> round_stroke_style_;
|
||||
BrushPtr current_brush_;
|
||||
Rect visible_size_;
|
||||
Matrix3x2 global_transform_;
|
||||
|
||||
mutable bool collecting_status_;
|
||||
mutable Status status_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#include <kiwano/renderer/Renderer.h>
|
||||
#include <kiwano/core/Logger.h>
|
||||
#include <kiwano/core/win32/helper.h>
|
||||
#include <kiwano/platform/Window.h>
|
||||
#include <kiwano/platform/FileSystem.h>
|
||||
|
|
@ -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;
|
||||
KGE_ASSERT(d3d_res_ && IsValid());
|
||||
|
||||
if (!IsValid())
|
||||
{
|
||||
hr = E_UNEXPECTED;
|
||||
}
|
||||
EndDraw();
|
||||
GetRenderTarget()->RestoreDrawingState(drawing_state_block_.get());
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
EndDraw();
|
||||
|
||||
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<const Size&>(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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,13 @@ namespace kiwano
|
|||
|
||||
HRESULT CreateDeviceIndependentResources();
|
||||
|
||||
public:
|
||||
HRESULT CreateDeviceResources(
|
||||
_In_ ComPtr<IDXGIDevice> dxgi_device,
|
||||
_In_ ComPtr<IDXGISwapChain> dxgi_swap_chain
|
||||
);
|
||||
|
||||
HRESULT CreateWindowSizeDependentResources();
|
||||
|
||||
HRESULT CreateBitmapConverter(
|
||||
_Out_ ComPtr<IWICFormatConverter>& converter,
|
||||
_In_opt_ ComPtr<IWICBitmapSource> source,
|
||||
|
|
@ -65,26 +71,31 @@ namespace kiwano
|
|||
|
||||
HRESULT CreateTextFormat(
|
||||
_Out_ ComPtr<IDWriteTextFormat>& text_format,
|
||||
_In_ String const& family,
|
||||
String const& family,
|
||||
_In_ ComPtr<IDWriteFontCollection> 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<IDWriteTextLayout>& text_layout,
|
||||
_In_ String const& text,
|
||||
String const& text,
|
||||
_In_ ComPtr<IDWriteTextFormat> text_format
|
||||
) override;
|
||||
|
||||
HRESULT SetD2DDevice(
|
||||
_In_ ComPtr<ID2D1Device> device
|
||||
HRESULT SetDpi(
|
||||
float dpi
|
||||
) override;
|
||||
|
||||
void SetTargetBitmap(
|
||||
_In_ ComPtr<ID2D1Bitmap1> target
|
||||
HRESULT SetLogicalSize(
|
||||
Size logical_size
|
||||
) override;
|
||||
|
||||
HRESULT HandleDeviceLost(
|
||||
_In_ ComPtr<IDXGIDevice> dxgi_device,
|
||||
_In_ ComPtr<IDXGISwapChain> dxgi_swap_chain
|
||||
) override;
|
||||
|
||||
void DiscardResources() override;
|
||||
|
|
@ -102,10 +113,15 @@ namespace kiwano
|
|||
private:
|
||||
unsigned long ref_count_;
|
||||
float dpi_;
|
||||
|
||||
ComPtr<IDXGISwapChain> dxgi_swap_chain_;
|
||||
};
|
||||
|
||||
|
||||
HRESULT ID2DDeviceResources::Create(ID2DDeviceResources** device_resources)
|
||||
HRESULT ID2DDeviceResources::Create(
|
||||
_Out_ ID2DDeviceResources** device_resources,
|
||||
_In_ ComPtr<IDXGIDevice> dxgi_device,
|
||||
_In_ ComPtr<IDXGISwapChain> 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<void**>(&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<IUnknown**>(&dwrite_factory)
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
dwrite_factory_ = dwrite_factory;
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT D2DDeviceResources::CreateDeviceResources(_In_ ComPtr<IDXGIDevice> dxgi_device, _In_ ComPtr<IDXGISwapChain> dxgi_swap_chain)
|
||||
{
|
||||
if (!factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
// Create the Direct2D device object and a corresponding context.
|
||||
ComPtr<ID2D1Device> device;
|
||||
HRESULT hr = factory_->CreateDevice(dxgi_device.get(), &device);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
dwrite_factory_ = dwrite_factory;
|
||||
ComPtr<ID2D1DeviceContext> device_ctx;
|
||||
|
||||
ComPtr<ID2D1StrokeStyle> miter_stroke_style;
|
||||
ComPtr<ID2D1StrokeStyle> bevel_stroke_style;
|
||||
ComPtr<ID2D1StrokeStyle> 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<ID2D1Device> device)
|
||||
HRESULT D2DDeviceResources::CreateWindowSizeDependentResources()
|
||||
{
|
||||
ComPtr<ID2D1DeviceContext> 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<IDXGISurface> 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<ID2D1Bitmap1> 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<ID2D1Bitmap1> 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<IDXGIDevice> dxgi_device, _In_ ComPtr<IDXGISwapChain> 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<IWICFormatConverter>& converter, _In_opt_ ComPtr<IWICBitmapSource> source,
|
||||
|
|
@ -440,8 +473,8 @@ namespace kiwano
|
|||
return hr;
|
||||
}
|
||||
|
||||
HRESULT D2DDeviceResources::CreateTextFormat(_Out_ ComPtr<IDWriteTextFormat> & text_format, _In_ String const& family, _In_ ComPtr<IDWriteFontCollection> 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<IDWriteTextFormat> & text_format, String const& family, _In_ ComPtr<IDWriteFontCollection> 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<IDWriteTextLayout>& text_layout, _In_ String const& text,
|
||||
HRESULT D2DDeviceResources::CreateTextLayout(_Out_ ComPtr<IDWriteTextLayout>& text_layout, String const& text,
|
||||
_In_ ComPtr<IDWriteTextFormat> text_format)
|
||||
{
|
||||
if (!dwrite_factory_)
|
||||
|
|
|
|||
|
|
@ -19,166 +19,12 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include <kiwano/math/math.h>
|
||||
#include <kiwano/core/Resource.h>
|
||||
#include <kiwano/core/win32/ComPtr.hpp>
|
||||
#include <kiwano/renderer/Color.h>
|
||||
#include <kiwano/renderer/win32/helper.h>
|
||||
#include <dwrite.h>
|
||||
#include <d2d1.h>
|
||||
#include <d2d1_1.h>
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
namespace DX
|
||||
{
|
||||
template <typename T>
|
||||
inline void SafeRelease(T*& ptr)
|
||||
{
|
||||
if (ptr != nullptr)
|
||||
{
|
||||
ptr->Release();
|
||||
ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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<D2D1_POINT_2F const&>(vec2);
|
||||
}
|
||||
|
||||
inline D2D1_POINT_2F& ConvertToPoint2F(Vec2& vec2)
|
||||
{
|
||||
return reinterpret_cast<D2D1_POINT_2F&>(vec2);
|
||||
}
|
||||
|
||||
inline const D2D1_POINT_2F* ConvertToPoint2F(const Vec2* vec2)
|
||||
{
|
||||
return reinterpret_cast<const D2D1_POINT_2F*>(vec2);
|
||||
}
|
||||
|
||||
inline D2D1_POINT_2F* ConvertToPoint2F(Vec2* vec2)
|
||||
{
|
||||
return reinterpret_cast<D2D1_POINT_2F*>(vec2);
|
||||
}
|
||||
|
||||
//
|
||||
// SizeF
|
||||
//
|
||||
|
||||
inline D2D1_SIZE_F const& ConvertToSizeF(Vec2 const& vec2)
|
||||
{
|
||||
return reinterpret_cast<D2D1_SIZE_F const&>(vec2);
|
||||
}
|
||||
|
||||
inline D2D1_SIZE_F& ConvertToSizeF(Vec2& vec2)
|
||||
{
|
||||
return reinterpret_cast<D2D1_SIZE_F&>(vec2);
|
||||
}
|
||||
|
||||
inline const D2D1_SIZE_F* ConvertToSizeF(const Vec2* vec2)
|
||||
{
|
||||
return reinterpret_cast<const D2D1_SIZE_F*>(vec2);
|
||||
}
|
||||
|
||||
inline D2D1_SIZE_F* ConvertToSizeF(Vec2* vec2)
|
||||
{
|
||||
return reinterpret_cast<D2D1_SIZE_F*>(vec2);
|
||||
}
|
||||
|
||||
//
|
||||
// RectF
|
||||
//
|
||||
|
||||
inline D2D1_RECT_F const& ConvertToRectF(Rect const& rect)
|
||||
{
|
||||
return reinterpret_cast<D2D1_RECT_F const&>(rect);
|
||||
}
|
||||
|
||||
inline D2D1_RECT_F& ConvertToRectF(Rect& rect)
|
||||
{
|
||||
return reinterpret_cast<D2D1_RECT_F&>(rect);
|
||||
}
|
||||
|
||||
inline const D2D1_RECT_F* ConvertToRectF(const Rect* rect)
|
||||
{
|
||||
return reinterpret_cast<const D2D1_RECT_F*>(rect);
|
||||
}
|
||||
|
||||
inline D2D1_RECT_F* ConvertToRectF(Rect* rect)
|
||||
{
|
||||
return reinterpret_cast<D2D1_RECT_F*>(rect);
|
||||
}
|
||||
|
||||
//
|
||||
// ColorF
|
||||
//
|
||||
inline D2D1_COLOR_F const& ConvertToColorF(Color const& color)
|
||||
{
|
||||
return reinterpret_cast<D2D1_COLOR_F const&>(color);
|
||||
}
|
||||
|
||||
inline D2D1_COLOR_F& ConvertToColorF(Color& color)
|
||||
{
|
||||
return reinterpret_cast<D2D1_COLOR_F&>(color);
|
||||
}
|
||||
|
||||
inline const D2D1_COLOR_F* ConvertToColorF(const Color* color)
|
||||
{
|
||||
return reinterpret_cast<const D2D1_COLOR_F*>(color);
|
||||
}
|
||||
|
||||
inline D2D1_COLOR_F* ConvertToColorF(Color* color)
|
||||
{
|
||||
return reinterpret_cast<D2D1_COLOR_F*>(color);
|
||||
}
|
||||
|
||||
//
|
||||
// MatrixF
|
||||
//
|
||||
|
||||
inline D2D1_MATRIX_3X2_F const& ConvertToMatrix3x2F(Matrix3x2 const& matrix)
|
||||
{
|
||||
return reinterpret_cast<D2D1_MATRIX_3X2_F const&>(matrix);
|
||||
}
|
||||
|
||||
inline D2D1_MATRIX_3X2_F& ConvertToMatrix3x2F(Matrix3x2& matrix)
|
||||
{
|
||||
return reinterpret_cast<D2D1_MATRIX_3X2_F&>(matrix);
|
||||
}
|
||||
|
||||
inline const D2D1_MATRIX_3X2_F* ConvertToMatrix3x2F(const Matrix3x2* matrix)
|
||||
{
|
||||
return reinterpret_cast<const D2D1_MATRIX_3X2_F*>(matrix);
|
||||
}
|
||||
|
||||
inline D2D1_MATRIX_3X2_F* ConvertToMatrix3x2F(Matrix3x2* matrix)
|
||||
{
|
||||
return reinterpret_cast<D2D1_MATRIX_3X2_F*>(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<IDXGIDevice> dxgi_device,
|
||||
_In_ ComPtr<IDXGISwapChain> dxgi_swap_chain
|
||||
);
|
||||
|
||||
virtual HRESULT CreateBitmapConverter(
|
||||
_Out_ ComPtr<IWICFormatConverter>& converter,
|
||||
|
|
@ -216,26 +66,31 @@ namespace kiwano
|
|||
|
||||
virtual HRESULT CreateTextFormat(
|
||||
_Out_ ComPtr<IDWriteTextFormat>& text_format,
|
||||
_In_ String const& family,
|
||||
String const& family,
|
||||
_In_ ComPtr<IDWriteFontCollection> 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<IDWriteTextLayout>& text_layout,
|
||||
_In_ String const& text,
|
||||
String const& text,
|
||||
_In_ ComPtr<IDWriteTextFormat> text_format
|
||||
) = 0;
|
||||
|
||||
virtual HRESULT SetD2DDevice(
|
||||
_In_ ComPtr<ID2D1Device> device
|
||||
virtual HRESULT SetDpi(
|
||||
float dpi
|
||||
) = 0;
|
||||
|
||||
virtual void SetTargetBitmap(
|
||||
_In_ ComPtr<ID2D1Bitmap1> target
|
||||
virtual HRESULT SetLogicalSize(
|
||||
Size logical_size
|
||||
) = 0;
|
||||
|
||||
virtual HRESULT HandleDeviceLost(
|
||||
_In_ ComPtr<IDXGIDevice> dxgi_device,
|
||||
_In_ ComPtr<IDXGISwapChain> 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<ID2D1Factory1> factory_;
|
||||
ComPtr<ID2D1Device> device_;
|
||||
|
|
@ -259,10 +110,6 @@ namespace kiwano
|
|||
|
||||
ComPtr<IWICImagingFactory> imaging_factory_;
|
||||
ComPtr<IDWriteFactory> dwrite_factory_;
|
||||
|
||||
ComPtr<ID2D1StrokeStyle> miter_stroke_style_;
|
||||
ComPtr<ID2D1StrokeStyle> bevel_stroke_style_;
|
||||
ComPtr<ID2D1StrokeStyle> round_stroke_style_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,8 +118,6 @@ namespace kiwano
|
|||
Size logical_size_;
|
||||
Size output_size_;
|
||||
unsigned long ref_count_;
|
||||
|
||||
ComPtr<ID2DDeviceResources> 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<IDXGIAdapter> dxgi_adapter;
|
||||
ComPtr<IDXGIDevice> dxgi_device;
|
||||
ComPtr<IDXGIFactory> dxgi_factory;
|
||||
ComPtr<ID2D1Device> d2d_device;
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ComPtr<IDXGIDevice> 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<IDXGIAdapter> dxgi_adapter;
|
||||
hr = dxgi_device_->GetAdapter(&dxgi_adapter);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
dxgi_factory_ = dxgi_factory;
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ComPtr<IDXGIFactory> 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<IDXGIDevice> dxgi_device;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = device_->QueryInterface(&dxgi_device);
|
||||
}
|
||||
|
||||
ComPtr<IDXGIAdapter> dxgi_adapter;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = dxgi_device->GetAdapter(&dxgi_adapter);
|
||||
}
|
||||
|
||||
ComPtr<IDXGIFactory> 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<IDXGISurface> dxgi_back_buffer;
|
||||
hr = dxgi_swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dxgi_back_buffer));
|
||||
|
||||
ComPtr<ID2D1Bitmap1> 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;
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <kiwano/macros.h>
|
||||
|
||||
#include <kiwano/renderer/win32/D2DDeviceResources.h>
|
||||
#include <kiwano/renderer/win32/helper.h>
|
||||
#include <kiwano/renderer/win32/D3DDeviceResourcesBase.h>
|
||||
#include <d3d10_1.h>
|
||||
|
||||
|
|
@ -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<ID3D10Device> device_;
|
||||
ComPtr<ID3D10RenderTargetView> rt_view_;
|
||||
ComPtr<ID3D10DepthStencilView> ds_view_;
|
||||
ComPtr<IDXGISwapChain> dxgi_swap_chain_;
|
||||
ComPtr<IDXGIFactory> dxgi_factory_;
|
||||
ComPtr<IDXGIDevice> dxgi_device_;
|
||||
ComPtr<IDXGISwapChain> dxgi_swap_chain_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#include <kiwano/renderer/win32/D3D11DeviceResources.h>
|
||||
|
||||
#include <kiwano/core/Logger.h>
|
||||
|
||||
#include <versionhelpers.h> // IsWindows10OrGreater
|
||||
|
||||
#pragma comment(lib, "d3d11.lib")
|
||||
|
|
@ -95,7 +95,6 @@ namespace kiwano
|
|||
unsigned long ref_count_;
|
||||
|
||||
D3D_FEATURE_LEVEL d3d_feature_level_;
|
||||
ComPtr<ID2DDeviceResources> 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<IDXGIAdapter> dxgi_adapter;
|
||||
ComPtr<IDXGIDevice> dxgi_device;
|
||||
ComPtr<IDXGIFactory> dxgi_factory;
|
||||
ComPtr<ID2D1Device> d2d_device;
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ComPtr<IDXGIDevice> 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<IDXGIAdapter> dxgi_adapter;
|
||||
hr = dxgi_device_->GetAdapter(&dxgi_adapter);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
dxgi_factory_ = dxgi_factory;
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
ComPtr<IDXGIFactory> 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<IDXGIDevice> dxgi_device;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = device_->QueryInterface(&dxgi_device);
|
||||
}
|
||||
|
||||
ComPtr<IDXGIAdapter> dxgi_adapter;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = dxgi_device->GetAdapter(&dxgi_adapter);
|
||||
}
|
||||
|
||||
ComPtr<IDXGIFactory> 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<IDXGISurface> dxgi_back_buffer;
|
||||
hr = dxgi_swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dxgi_back_buffer));
|
||||
|
||||
ComPtr<ID2D1Bitmap1> 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;
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <kiwano/macros.h>
|
||||
|
||||
#include <kiwano/renderer/win32/D2DDeviceResources.h>
|
||||
#include <kiwano/renderer/win32/helper.h>
|
||||
#include <kiwano/renderer/win32/D3DDeviceResourcesBase.h>
|
||||
#include <d3d11.h>
|
||||
|
||||
|
|
@ -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<ID3D11DeviceContext> device_context_;
|
||||
ComPtr<ID3D11RenderTargetView> rt_view_;
|
||||
ComPtr<ID3D11DepthStencilView> ds_view_;
|
||||
ComPtr<IDXGISwapChain> dxgi_swap_chain_;
|
||||
ComPtr<IDXGIFactory> dxgi_factory_;
|
||||
ComPtr<IDXGIDevice> dxgi_device_;
|
||||
ComPtr<IDXGISwapChain> dxgi_swap_chain_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 <kiwano/math/math.h>
|
||||
#include <kiwano/core/win32/ComPtr.hpp>
|
||||
#include <kiwano/renderer/Color.h>
|
||||
#include <d2d1.h>
|
||||
|
||||
namespace kiwano
|
||||
{
|
||||
namespace DX
|
||||
{
|
||||
template <typename T>
|
||||
inline void SafeRelease(T*& ptr)
|
||||
{
|
||||
if (ptr != nullptr)
|
||||
{
|
||||
ptr->Release();
|
||||
ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
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<D2D1_POINT_2F const&>(vec2);
|
||||
}
|
||||
|
||||
inline D2D1_POINT_2F& ConvertToPoint2F(Vec2& vec2)
|
||||
{
|
||||
return reinterpret_cast<D2D1_POINT_2F&>(vec2);
|
||||
}
|
||||
|
||||
inline const D2D1_POINT_2F* ConvertToPoint2F(const Vec2* vec2)
|
||||
{
|
||||
return reinterpret_cast<const D2D1_POINT_2F*>(vec2);
|
||||
}
|
||||
|
||||
inline D2D1_POINT_2F* ConvertToPoint2F(Vec2* vec2)
|
||||
{
|
||||
return reinterpret_cast<D2D1_POINT_2F*>(vec2);
|
||||
}
|
||||
|
||||
//
|
||||
// SizeF
|
||||
//
|
||||
|
||||
inline D2D1_SIZE_F const& ConvertToSizeF(Vec2 const& vec2)
|
||||
{
|
||||
return reinterpret_cast<D2D1_SIZE_F const&>(vec2);
|
||||
}
|
||||
|
||||
inline D2D1_SIZE_F& ConvertToSizeF(Vec2& vec2)
|
||||
{
|
||||
return reinterpret_cast<D2D1_SIZE_F&>(vec2);
|
||||
}
|
||||
|
||||
inline const D2D1_SIZE_F* ConvertToSizeF(const Vec2* vec2)
|
||||
{
|
||||
return reinterpret_cast<const D2D1_SIZE_F*>(vec2);
|
||||
}
|
||||
|
||||
inline D2D1_SIZE_F* ConvertToSizeF(Vec2* vec2)
|
||||
{
|
||||
return reinterpret_cast<D2D1_SIZE_F*>(vec2);
|
||||
}
|
||||
|
||||
//
|
||||
// RectF
|
||||
//
|
||||
|
||||
inline D2D1_RECT_F const& ConvertToRectF(Rect const& rect)
|
||||
{
|
||||
return reinterpret_cast<D2D1_RECT_F const&>(rect);
|
||||
}
|
||||
|
||||
inline D2D1_RECT_F& ConvertToRectF(Rect& rect)
|
||||
{
|
||||
return reinterpret_cast<D2D1_RECT_F&>(rect);
|
||||
}
|
||||
|
||||
inline const D2D1_RECT_F* ConvertToRectF(const Rect* rect)
|
||||
{
|
||||
return reinterpret_cast<const D2D1_RECT_F*>(rect);
|
||||
}
|
||||
|
||||
inline D2D1_RECT_F* ConvertToRectF(Rect* rect)
|
||||
{
|
||||
return reinterpret_cast<D2D1_RECT_F*>(rect);
|
||||
}
|
||||
|
||||
//
|
||||
// ColorF
|
||||
//
|
||||
inline D2D1_COLOR_F const& ConvertToColorF(Color const& color)
|
||||
{
|
||||
return reinterpret_cast<D2D1_COLOR_F const&>(color);
|
||||
}
|
||||
|
||||
inline D2D1_COLOR_F& ConvertToColorF(Color& color)
|
||||
{
|
||||
return reinterpret_cast<D2D1_COLOR_F&>(color);
|
||||
}
|
||||
|
||||
inline const D2D1_COLOR_F* ConvertToColorF(const Color* color)
|
||||
{
|
||||
return reinterpret_cast<const D2D1_COLOR_F*>(color);
|
||||
}
|
||||
|
||||
inline D2D1_COLOR_F* ConvertToColorF(Color* color)
|
||||
{
|
||||
return reinterpret_cast<D2D1_COLOR_F*>(color);
|
||||
}
|
||||
|
||||
//
|
||||
// MatrixF
|
||||
//
|
||||
|
||||
inline D2D1_MATRIX_3X2_F const& ConvertToMatrix3x2F(Matrix3x2 const& matrix)
|
||||
{
|
||||
return reinterpret_cast<D2D1_MATRIX_3X2_F const&>(matrix);
|
||||
}
|
||||
|
||||
inline D2D1_MATRIX_3X2_F& ConvertToMatrix3x2F(Matrix3x2& matrix)
|
||||
{
|
||||
return reinterpret_cast<D2D1_MATRIX_3X2_F&>(matrix);
|
||||
}
|
||||
|
||||
inline const D2D1_MATRIX_3X2_F* ConvertToMatrix3x2F(const Matrix3x2* matrix)
|
||||
{
|
||||
return reinterpret_cast<const D2D1_MATRIX_3X2_F*>(matrix);
|
||||
}
|
||||
|
||||
inline D2D1_MATRIX_3X2_F* ConvertToMatrix3x2F(Matrix3x2* matrix)
|
||||
{
|
||||
return reinterpret_cast<D2D1_MATRIX_3X2_F*>(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.
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue