d3d11 support
This commit is contained in:
parent
1f8b0bb058
commit
074af87127
|
|
@ -216,7 +216,7 @@ int main()
|
|||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
::MessageBoxA(nullptr, e.what(), "An exception has occurred!", MB_ICONERROR | MB_TASKMODAL);
|
||||
::MessageBoxA(nullptr, e.what(), "An exception has occurred!", MB_ICONERROR | MB_OK);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,12 +13,10 @@
|
|||
<ClInclude Include="..\..\src\core\closure.hpp" />
|
||||
<ClInclude Include="..\..\src\core\Color.h" />
|
||||
<ClInclude Include="..\..\src\core\config.h" />
|
||||
<ClInclude Include="..\..\src\core\d2dhelper.hpp" />
|
||||
<ClInclude Include="..\..\src\core\DebugNode.h" />
|
||||
<ClInclude Include="..\..\src\core\Event.hpp" />
|
||||
<ClInclude Include="..\..\src\core\EventDispatcher.h" />
|
||||
<ClInclude Include="..\..\src\core\EventListener.h" />
|
||||
<ClInclude Include="..\..\src\core\Factory.h" />
|
||||
<ClInclude Include="..\..\src\core\Font.hpp" />
|
||||
<ClInclude Include="..\..\src\core\Frames.h" />
|
||||
<ClInclude Include="..\..\src\core\Application.h" />
|
||||
|
|
@ -47,16 +45,20 @@
|
|||
<ClInclude Include="..\..\src\core\Task.h" />
|
||||
<ClInclude Include="..\..\src\core\TaskManager.h" />
|
||||
<ClInclude Include="..\..\src\core\Text.h" />
|
||||
<ClInclude Include="..\..\src\core\TextRenderer.h" />
|
||||
<ClInclude Include="..\..\src\core\TextStyle.hpp" />
|
||||
<ClInclude Include="..\..\src\core\time.h" />
|
||||
<ClInclude Include="..\..\src\core\Transform.hpp" />
|
||||
<ClInclude Include="..\..\src\core\Transition.h" />
|
||||
<ClInclude Include="..\..\src\core\window.h" />
|
||||
<ClInclude Include="..\..\src\dx\D2DDeviceResources.h" />
|
||||
<ClInclude Include="..\..\src\dx\D3D11DeviceResources.h" />
|
||||
<ClInclude Include="..\..\src\dx\DeviceResources.h" />
|
||||
<ClInclude Include="..\..\src\dx\helper.hpp" />
|
||||
<ClInclude Include="..\..\src\dx\TextRenderer.h" />
|
||||
<ClInclude Include="..\..\src\easy2d.h" />
|
||||
<ClInclude Include="..\..\src\math\constants.hpp" />
|
||||
<ClInclude Include="..\..\src\math\ease.hpp" />
|
||||
<ClInclude Include="..\..\src\math\Matrix.h" />
|
||||
<ClInclude Include="..\..\src\math\Matrix.hpp" />
|
||||
<ClInclude Include="..\..\src\math\rand.h" />
|
||||
<ClInclude Include="..\..\src\math\Rect.hpp" />
|
||||
<ClInclude Include="..\..\src\math\scalar.hpp" />
|
||||
|
|
@ -83,7 +85,6 @@
|
|||
<ClCompile Include="..\..\src\core\DebugNode.cpp" />
|
||||
<ClCompile Include="..\..\src\core\EventDispatcher.cpp" />
|
||||
<ClCompile Include="..\..\src\core\EventListener.cpp" />
|
||||
<ClCompile Include="..\..\src\core\Factory.cpp" />
|
||||
<ClCompile Include="..\..\src\core\Frames.cpp" />
|
||||
<ClCompile Include="..\..\src\core\Application.cpp" />
|
||||
<ClCompile Include="..\..\src\core\Geometry.cpp" />
|
||||
|
|
@ -102,11 +103,12 @@
|
|||
<ClCompile Include="..\..\src\core\Task.cpp" />
|
||||
<ClCompile Include="..\..\src\core\TaskManager.cpp" />
|
||||
<ClCompile Include="..\..\src\core\Text.cpp" />
|
||||
<ClCompile Include="..\..\src\core\TextRenderer.cpp" />
|
||||
<ClCompile Include="..\..\src\core\time.cpp" />
|
||||
<ClCompile Include="..\..\src\core\Transition.cpp" />
|
||||
<ClCompile Include="..\..\src\core\window.cpp" />
|
||||
<ClCompile Include="..\..\src\math\Matrix.cpp" />
|
||||
<ClCompile Include="..\..\src\dx\D2DDeviceResources.cpp" />
|
||||
<ClCompile Include="..\..\src\dx\D3D11DeviceResources.cpp" />
|
||||
<ClCompile Include="..\..\src\dx\TextRenderer.cpp" />
|
||||
<ClCompile Include="..\..\src\math\rand.cpp" />
|
||||
<ClCompile Include="..\..\src\ui\Button.cpp" />
|
||||
<ClCompile Include="..\..\src\ui\Menu.cpp" />
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@
|
|||
<Filter Include="ui">
|
||||
<UniqueIdentifier>{07b6d541-4a1b-472a-aae0-daf9d082fe84}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="dx">
|
||||
<UniqueIdentifier>{a9793a75-3212-4e31-a443-b23f18a1e136}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\src\easy2d.h" />
|
||||
|
|
@ -64,9 +67,6 @@
|
|||
<ClInclude Include="..\..\src\core\Text.h">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\TextRenderer.h">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\time.h">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -154,9 +154,6 @@
|
|||
<ClInclude Include="..\..\src\math\constants.hpp">
|
||||
<Filter>math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\Factory.h">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\EventDispatcher.h">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -169,9 +166,6 @@
|
|||
<ClInclude Include="..\..\src\core\helper.hpp">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\d2dhelper.hpp">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\keys.hpp">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -208,9 +202,6 @@
|
|||
<ClInclude Include="..\..\src\core\ActionHelper.h">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\math\Matrix.h">
|
||||
<Filter>math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\core\Array.h">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
|
|
@ -220,6 +211,24 @@
|
|||
<ClInclude Include="..\..\src\core\Action.h">
|
||||
<Filter>core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\math\Matrix.hpp">
|
||||
<Filter>math</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\dx\D2DDeviceResources.h">
|
||||
<Filter>dx</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\dx\D3D11DeviceResources.h">
|
||||
<Filter>dx</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\dx\DeviceResources.h">
|
||||
<Filter>dx</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\dx\helper.hpp">
|
||||
<Filter>dx</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\dx\TextRenderer.h">
|
||||
<Filter>dx</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\core\Animation.cpp">
|
||||
|
|
@ -264,9 +273,6 @@
|
|||
<ClCompile Include="..\..\src\core\Text.cpp">
|
||||
<Filter>core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\TextRenderer.cpp">
|
||||
<Filter>core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\time.cpp">
|
||||
<Filter>core</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -327,9 +333,6 @@
|
|||
<ClCompile Include="..\..\src\core\Frames.cpp">
|
||||
<Filter>core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\Factory.cpp">
|
||||
<Filter>core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\EventDispatcher.cpp">
|
||||
<Filter>core</Filter>
|
||||
</ClCompile>
|
||||
|
|
@ -351,11 +354,17 @@
|
|||
<ClCompile Include="..\..\src\core\ActionGroup.cpp">
|
||||
<Filter>core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\math\Matrix.cpp">
|
||||
<Filter>math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\core\Action.cpp">
|
||||
<Filter>core</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\dx\D2DDeviceResources.cpp">
|
||||
<Filter>dx</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\dx\D3D11DeviceResources.cpp">
|
||||
<Filter>dx</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\dx\TextRenderer.cpp">
|
||||
<Filter>dx</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -13,9 +13,11 @@ public:
|
|||
{
|
||||
// 创建文字节点
|
||||
easy2d::TextPtr text = new easy2d::Text(L"Hello Easy2D!");
|
||||
// 修改节点位置
|
||||
// 设置节点大小为文字布局大小
|
||||
text->SetSize(text->GetLayoutSize());
|
||||
// 修改节点位置, 使节点在屏幕上居中
|
||||
text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2);
|
||||
// 修改节点锚点, 使节点在屏幕上居中
|
||||
// 修改节点锚点, 使文字中心对齐屏幕中心
|
||||
text->SetAnchor(0.5, 0.5);
|
||||
// 添加到场景中
|
||||
this->AddChild(text);
|
||||
|
|
@ -46,7 +48,7 @@ int main()
|
|||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
::MessageBoxA(nullptr, e.what(), "An exception has occurred!", MB_ICONERROR | MB_TASKMODAL);
|
||||
::MessageBoxA(nullptr, e.what(), "An exception has occurred!", MB_ICONERROR | MB_OK);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ public:
|
|||
{
|
||||
// 创建文本
|
||||
TextPtr text = new Text(L"Hello Easy2D!");
|
||||
// 设置节点大小为文字布局大小
|
||||
text->SetSize(text->GetLayoutSize());
|
||||
// 让文本显示在屏幕中央
|
||||
text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2);
|
||||
text->SetAnchor(0.5, 0.5);
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ public:
|
|||
|
||||
// 创建说明文字
|
||||
TextPtr text = new Text(L"按上下左右键移动\n按鼠标左键旋转\n点击鼠标右键隐藏");
|
||||
// 设置节点大小为文字布局大小
|
||||
text->SetSize(text->GetLayoutSize());
|
||||
// 设置文字位置
|
||||
text->SetAnchor(0.5f, 0.5f);
|
||||
text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT - 50);
|
||||
|
|
|
|||
|
|
@ -33,18 +33,15 @@ public:
|
|||
|
||||
// 创建说明文字
|
||||
TextPtr intro_text = new Text(L"按上下键调整音量\n按空格键暂停或继续");
|
||||
intro_text->SetAnchor(0.5f, 0.5f);
|
||||
intro_text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2 - 50);
|
||||
intro_text->SetPosition(WINDOW_WIDTH / 2 - 80, WINDOW_HEIGHT / 2 - 50);
|
||||
|
||||
// 创建音量文字
|
||||
volume_text = new Text(L"当前音量:");
|
||||
volume_text->SetAnchor(0.5f, 0.5f);
|
||||
volume_text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2 + 30);
|
||||
volume_text->SetPosition(WINDOW_WIDTH / 2 - 80, WINDOW_HEIGHT / 2 + 30);
|
||||
|
||||
// 创建状态文字
|
||||
state_text = new Text(L"当前状态:");
|
||||
state_text->SetAnchor(0.5f, 0.5f);
|
||||
state_text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2 + 60);
|
||||
state_text->SetPosition(WINDOW_WIDTH / 2 - 80, WINDOW_HEIGHT / 2 + 60);
|
||||
|
||||
// 添加到场景
|
||||
this->AddChild(intro_text);
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ int main()
|
|||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
::MessageBoxA(nullptr, e.what(), "An exception has occurred!", MB_ICONERROR | MB_TASKMODAL);
|
||||
::MessageBoxA(nullptr, e.what(), "An exception has occurred!", MB_ICONERROR | MB_OK);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
#include "Application.h"
|
||||
#include "logs.h"
|
||||
#include "modules.h"
|
||||
#include "Factory.h"
|
||||
#include "render.h"
|
||||
#include "Event.hpp"
|
||||
#include "Scene.h"
|
||||
#include "DebugNode.h"
|
||||
|
|
@ -37,7 +37,6 @@ namespace easy2d
|
|||
Application::Application(String const& app_name)
|
||||
: end_(true)
|
||||
, inited_(false)
|
||||
, debug_(false)
|
||||
, curr_scene_(nullptr)
|
||||
, next_scene_(nullptr)
|
||||
, transition_(nullptr)
|
||||
|
|
@ -56,44 +55,6 @@ namespace easy2d
|
|||
|
||||
void Application::Init(const Options& options)
|
||||
{
|
||||
debug_ = options.debug;
|
||||
|
||||
// show console if debug mode enabled
|
||||
if (debug_ && !::GetConsoleWindow())
|
||||
{
|
||||
if (!::AllocConsole())
|
||||
{
|
||||
E2D_WARNING_LOG(L"AllocConsole failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
HWND console = ::GetConsoleWindow();
|
||||
FILE * dummy;
|
||||
freopen_s(&dummy, "CONOUT$", "w+t", stdout);
|
||||
freopen_s(&dummy, "CONIN$", "r+t", stdin);
|
||||
freopen_s(&dummy, "CONOUT$", "w+t", stderr);
|
||||
(void)dummy;
|
||||
|
||||
std::cout.clear();
|
||||
std::wcout.clear();
|
||||
std::cin.clear();
|
||||
std::wcin.clear();
|
||||
std::cerr.clear();
|
||||
std::wcerr.clear();
|
||||
|
||||
// disable the close button of console
|
||||
if (console)
|
||||
{
|
||||
HMENU hmenu = ::GetSystemMenu(console, FALSE);
|
||||
::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ThrowIfFailed(
|
||||
Factory::Instance().Init(debug_)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
Window::Instance().Init(
|
||||
options.title,
|
||||
|
|
@ -101,30 +62,26 @@ namespace easy2d
|
|||
options.height,
|
||||
options.icon,
|
||||
options.fullscreen,
|
||||
Application::WndProc,
|
||||
debug_
|
||||
Application::WndProc
|
||||
)
|
||||
);
|
||||
|
||||
HWND hwnd = Window::Instance().GetHandle();
|
||||
|
||||
ThrowIfFailed(
|
||||
RenderSystem::Instance().Init(
|
||||
hwnd,
|
||||
options.vsync,
|
||||
debug_
|
||||
)
|
||||
Renderer::Instance().Init(hwnd)
|
||||
);
|
||||
|
||||
Renderer::Instance().SetClearColor(options.clear_color);
|
||||
|
||||
ThrowIfFailed(
|
||||
Input::Instance().Init(
|
||||
hwnd,
|
||||
debug_
|
||||
hwnd
|
||||
)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
Audio::Instance().Init(debug_)
|
||||
Audio::Instance().Init()
|
||||
);
|
||||
|
||||
OnStart();
|
||||
|
|
@ -173,9 +130,8 @@ namespace easy2d
|
|||
curr_scene_.Reset();
|
||||
|
||||
Audio::Instance().Destroy();
|
||||
RenderSystem::Instance().Destroy();
|
||||
Renderer::Instance().Destroy();
|
||||
Window::Instance().Destroy();
|
||||
Factory::Instance().Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -251,16 +207,14 @@ namespace easy2d
|
|||
if (next_scene_)
|
||||
next_scene_->Update(dt);
|
||||
|
||||
if (debug_)
|
||||
if (DebugNode::IsShown())
|
||||
DebugNode::Instance().Update(dt);
|
||||
}
|
||||
|
||||
void Application::Render(HWND hwnd)
|
||||
{
|
||||
auto& rt = RenderSystem::Instance();
|
||||
|
||||
ThrowIfFailed(
|
||||
rt.BeginDraw(hwnd)
|
||||
Renderer::Instance().BeginDraw()
|
||||
);
|
||||
|
||||
if (transition_)
|
||||
|
|
@ -272,16 +226,50 @@ namespace easy2d
|
|||
curr_scene_->Render();
|
||||
}
|
||||
|
||||
if (debug_)
|
||||
if (DebugNode::IsShown())
|
||||
DebugNode::Instance().Render();
|
||||
|
||||
ThrowIfFailed(
|
||||
rt.EndDraw()
|
||||
Renderer::Instance().EndDraw()
|
||||
);
|
||||
|
||||
::InvalidateRect(hwnd, NULL, FALSE);
|
||||
}
|
||||
|
||||
void Application::AllocConsole()
|
||||
{
|
||||
if (!::GetConsoleWindow())
|
||||
{
|
||||
if (!::AllocConsole())
|
||||
{
|
||||
E2D_WARNING_LOG(L"AllocConsole failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
HWND console = ::GetConsoleWindow();
|
||||
FILE * dummy;
|
||||
freopen_s(&dummy, "CONOUT$", "w+t", stdout);
|
||||
freopen_s(&dummy, "CONIN$", "r+t", stdin);
|
||||
freopen_s(&dummy, "CONOUT$", "w+t", stderr);
|
||||
(void)dummy;
|
||||
|
||||
std::cout.clear();
|
||||
std::wcout.clear();
|
||||
std::cin.clear();
|
||||
std::wcin.clear();
|
||||
std::cerr.clear();
|
||||
std::wcerr.clear();
|
||||
|
||||
// disable the close button of console
|
||||
if (console)
|
||||
{
|
||||
HMENU hmenu = ::GetSystemMenu(console, FALSE);
|
||||
::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK Application::WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
Application * app = reinterpret_cast<Application*>(
|
||||
|
|
@ -363,10 +351,7 @@ namespace easy2d
|
|||
UINT width = LOWORD(lparam);
|
||||
UINT height = HIWORD(lparam);
|
||||
|
||||
// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染
|
||||
// 目标的大小。它可能会调用失败,但是这里可以忽略有可能的
|
||||
// 错误,因为这个错误将在下一次调用 EndDraw 时产生
|
||||
RenderSystem::Instance().Resize(width, height);
|
||||
Renderer::Instance().GetDeviceResources()->SetLogicalSize(Size{ (float)width, (float)height });
|
||||
|
||||
if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@
|
|||
#include "include-forwards.h"
|
||||
#include "time.h"
|
||||
#include "window.h"
|
||||
#include "render.h"
|
||||
#include "input.h"
|
||||
#include "audio.h"
|
||||
|
||||
|
|
@ -30,22 +29,22 @@ namespace easy2d
|
|||
{
|
||||
struct Options
|
||||
{
|
||||
String title; // 标题
|
||||
int width; // 宽度
|
||||
int height; // 高度
|
||||
LPCWSTR icon; // 图标
|
||||
bool vsync; // 垂直同步
|
||||
bool fullscreen; // 全屏模式
|
||||
bool debug; // 调试模式
|
||||
String title; // 标题
|
||||
int width; // 宽度
|
||||
int height; // 高度
|
||||
LPCWSTR icon; // 图标
|
||||
Color clear_color; // 清屏颜色
|
||||
bool vsync; // 垂直同步
|
||||
bool fullscreen; // 全屏模式
|
||||
|
||||
Options()
|
||||
: title(L"Easy2D Game")
|
||||
, width(640)
|
||||
, height(480)
|
||||
, icon(nullptr)
|
||||
, clear_color(Color::Black)
|
||||
, vsync(true)
|
||||
, fullscreen(false)
|
||||
, debug(false)
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
@ -105,6 +104,9 @@ namespace easy2d
|
|||
float scale_factor
|
||||
);
|
||||
|
||||
// 分配控制台
|
||||
static void AllocConsole();
|
||||
|
||||
private:
|
||||
void Render(HWND);
|
||||
|
||||
|
|
@ -115,7 +117,6 @@ namespace easy2d
|
|||
private:
|
||||
bool end_;
|
||||
bool inited_;
|
||||
bool debug_;
|
||||
float time_scale_;
|
||||
String app_name_;
|
||||
ScenePtr curr_scene_;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
#include "logs.h"
|
||||
#include "Image.h"
|
||||
#include "Geometry.h"
|
||||
#include "Factory.h"
|
||||
#include "render.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
|
@ -31,37 +31,30 @@ namespace easy2d
|
|||
: cache_expired_(false)
|
||||
, stroke_width_(1.0f)
|
||||
{
|
||||
auto ctx = Renderer::Instance().GetDeviceResources()->GetD2DDeviceContext();
|
||||
|
||||
ThrowIfFailed(
|
||||
RenderSystem::Instance().CreateBitmapRenderTarget(render_target_)
|
||||
ctx->CreateCompatibleRenderTarget(&render_target_)
|
||||
);
|
||||
|
||||
auto properties = D2D1::BrushProperties();
|
||||
ThrowIfFailed(
|
||||
render_target_->CreateSolidColorBrush(
|
||||
D2D1::ColorF(0, 0, 0, 0),
|
||||
properties,
|
||||
D2D1::BrushProperties(),
|
||||
&fill_brush_)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
render_target_->CreateSolidColorBrush(
|
||||
D2D1::ColorF(Color::White),
|
||||
properties,
|
||||
D2D1::BrushProperties(),
|
||||
&stroke_brush_)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
render_target_->CreateSolidColorBrush(
|
||||
D2D1::ColorF(Color::White),
|
||||
properties,
|
||||
&text_brush_)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
Factory::Instance().CreateTextRenderer(
|
||||
text_renderer_,
|
||||
render_target_,
|
||||
text_brush_
|
||||
ITextRenderer::Create(
|
||||
&text_renderer_,
|
||||
render_target_.Get()
|
||||
)
|
||||
);
|
||||
|
||||
|
|
@ -105,18 +98,18 @@ namespace easy2d
|
|||
|
||||
if (bitmap_cached_)
|
||||
{
|
||||
RenderSystem::Instance().DrawBitmap(bitmap_cached_);
|
||||
Renderer::Instance().DrawBitmap(bitmap_cached_);
|
||||
}
|
||||
}
|
||||
|
||||
void Canvas::SetStrokeColor(Color const& color)
|
||||
{
|
||||
stroke_brush_->SetColor(ToD2dColorF(color));
|
||||
stroke_brush_->SetColor(DX::ConvertToColorF(color));
|
||||
}
|
||||
|
||||
void Canvas::SetFillColor(Color const& color)
|
||||
{
|
||||
fill_brush_->SetColor(ToD2dColorF(color));
|
||||
fill_brush_->SetColor(DX::ConvertToColorF(color));
|
||||
}
|
||||
|
||||
void Canvas::SetStrokeWidth(float width)
|
||||
|
|
@ -126,7 +119,7 @@ namespace easy2d
|
|||
|
||||
void Canvas::SetOutlineJoinStyle(StrokeStyle outline_join)
|
||||
{
|
||||
outline_join_style_ = Factory::Instance().GetStrokeStyle(outline_join);
|
||||
outline_join_style_ = Renderer::Instance().GetDeviceResources()->GetStrokeStyle(outline_join);
|
||||
}
|
||||
|
||||
void Canvas::SetTextStyle(Font const& font, TextStyle const & text_style)
|
||||
|
|
@ -135,12 +128,15 @@ namespace easy2d
|
|||
text_style_ = text_style;
|
||||
|
||||
text_renderer_->SetTextStyle(
|
||||
ToD2dColorF(text_style_.color),
|
||||
DX::ConvertToColorF(text_style_.color),
|
||||
text_style_.outline,
|
||||
ToD2dColorF(text_style_.outline_color),
|
||||
DX::ConvertToColorF(text_style_.outline_color),
|
||||
text_style_.outline_width,
|
||||
Factory::Instance().GetStrokeStyle(text_style_.outline_stroke).Get()
|
||||
Renderer::Instance().GetDeviceResources()->GetStrokeStyle(text_style_.outline_stroke)
|
||||
);
|
||||
|
||||
// clear text format
|
||||
text_format_ = nullptr;
|
||||
}
|
||||
|
||||
Color Canvas::GetStrokeColor() const
|
||||
|
|
@ -162,7 +158,7 @@ namespace easy2d
|
|||
|
||||
void Canvas::SetBrushTransform(Matrix const & transform)
|
||||
{
|
||||
render_target_->SetTransform(transform);
|
||||
render_target_->SetTransform(DX::ConvertToMatrix3x2F(transform));
|
||||
}
|
||||
|
||||
void Canvas::DrawLine(const Point & begin, const Point & end)
|
||||
|
|
@ -258,7 +254,7 @@ namespace easy2d
|
|||
D2D1::RectF(0, 0, image->GetWidth(), image->GetHeight()),
|
||||
opacity,
|
||||
D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
|
||||
ToD2dRectF(image->GetCropRect())
|
||||
DX::ConvertToRectF(image->GetCropRect())
|
||||
);
|
||||
cache_expired_ = true;
|
||||
}
|
||||
|
|
@ -269,23 +265,25 @@ namespace easy2d
|
|||
if (text.empty())
|
||||
return;
|
||||
|
||||
D2DTextFormatPtr text_format;
|
||||
ThrowIfFailed(
|
||||
Factory::Instance().CreateTextFormat(
|
||||
text_format,
|
||||
text_font_,
|
||||
text_style_
|
||||
)
|
||||
);
|
||||
if (!text_format_)
|
||||
{
|
||||
ThrowIfFailed(
|
||||
Renderer::Instance().GetDeviceResources()->CreateTextFormat(
|
||||
text_format_,
|
||||
text_font_,
|
||||
text_style_
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
D2DTextLayoutPtr text_layout;
|
||||
ComPtr<IDWriteTextLayout> text_layout;
|
||||
Size layout_size;
|
||||
ThrowIfFailed(
|
||||
Factory::Instance().CreateTextLayout(
|
||||
Renderer::Instance().GetDeviceResources()->CreateTextLayout(
|
||||
text_layout,
|
||||
layout_size,
|
||||
text,
|
||||
text_format,
|
||||
text_format_,
|
||||
text_style_
|
||||
)
|
||||
);
|
||||
|
|
@ -390,14 +388,14 @@ namespace easy2d
|
|||
current_geometry_ = nullptr;
|
||||
|
||||
ThrowIfFailed(
|
||||
Factory::Instance().CreatePathGeometry(current_geometry_)
|
||||
Renderer::Instance().GetDeviceResources()->GetD2DFactory()->CreatePathGeometry(¤t_geometry_)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
current_geometry_->Open(¤t_sink_)
|
||||
);
|
||||
|
||||
current_sink_->BeginFigure(ToD2dPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED);
|
||||
current_sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED);
|
||||
}
|
||||
|
||||
void Canvas::EndPath(bool closed)
|
||||
|
|
@ -415,7 +413,7 @@ namespace easy2d
|
|||
void Canvas::AddLine(Point const & point)
|
||||
{
|
||||
if (current_sink_)
|
||||
current_sink_->AddLine(ToD2dPoint2F(point));
|
||||
current_sink_->AddLine(DX::ConvertToPoint2F(point));
|
||||
}
|
||||
|
||||
void Canvas::AddLines(Array<Point> const& points)
|
||||
|
|
@ -435,9 +433,9 @@ namespace easy2d
|
|||
{
|
||||
current_sink_->AddBezier(
|
||||
D2D1::BezierSegment(
|
||||
ToD2dPoint2F(point1),
|
||||
ToD2dPoint2F(point2),
|
||||
ToD2dPoint2F(point3)
|
||||
DX::ConvertToPoint2F(point1),
|
||||
DX::ConvertToPoint2F(point2),
|
||||
DX::ConvertToPoint2F(point3)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -449,8 +447,8 @@ namespace easy2d
|
|||
{
|
||||
current_sink_->AddArc(
|
||||
D2D1::ArcSegment(
|
||||
ToD2dPoint2F(point),
|
||||
ToD2dSizeF(radius),
|
||||
DX::ConvertToPoint2F(point),
|
||||
DX::ConvertToSizeF(radius),
|
||||
rotation,
|
||||
clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,
|
||||
is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE
|
||||
|
|
@ -492,7 +490,7 @@ namespace easy2d
|
|||
return image;
|
||||
}
|
||||
|
||||
D2DBitmapPtr const& easy2d::Canvas::GetBitmap() const
|
||||
ComPtr<ID2D1Bitmap> const& easy2d::Canvas::GetBitmap() const
|
||||
{
|
||||
if (cache_expired_)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "Node.h"
|
||||
#include "Font.hpp"
|
||||
#include "TextStyle.hpp"
|
||||
#include "TextRenderer.h"
|
||||
#include "../DX/TextRenderer.h"
|
||||
|
||||
#undef DrawText
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ namespace easy2d
|
|||
{
|
||||
// »²¼
|
||||
class E2D_API Canvas
|
||||
: public Node
|
||||
: public VisualNode
|
||||
{
|
||||
public:
|
||||
Canvas();
|
||||
|
|
@ -221,22 +221,23 @@ namespace easy2d
|
|||
void OnRender() override;
|
||||
|
||||
protected:
|
||||
D2DBitmapPtr const& GetBitmap() const;
|
||||
ComPtr<ID2D1Bitmap> const& GetBitmap() const;
|
||||
|
||||
protected:
|
||||
float stroke_width_;
|
||||
Font text_font_;
|
||||
TextStyle text_style_;
|
||||
D2DPathGeometryPtr current_geometry_;
|
||||
D2DGeometrySinkPtr current_sink_;
|
||||
D2DStrokeStylePtr outline_join_style_;
|
||||
D2DSolidColorBrushPtr fill_brush_;
|
||||
D2DSolidColorBrushPtr stroke_brush_;
|
||||
D2DSolidColorBrushPtr text_brush_;
|
||||
D2DTextRendererPtr text_renderer_;
|
||||
D2DBitmapRenderTargetPtr render_target_;
|
||||
|
||||
mutable bool cache_expired_;
|
||||
mutable D2DBitmapPtr bitmap_cached_;
|
||||
ComPtr<ID2D1PathGeometry> current_geometry_;
|
||||
ComPtr<ID2D1GeometrySink> current_sink_;
|
||||
ComPtr<ID2D1StrokeStyle> outline_join_style_;
|
||||
ComPtr<ID2D1SolidColorBrush> fill_brush_;
|
||||
ComPtr<ID2D1SolidColorBrush> stroke_brush_;
|
||||
ComPtr<IDWriteTextFormat> text_format_;
|
||||
ComPtr<ITextRenderer> text_renderer_;
|
||||
ComPtr<ID2D1BitmapRenderTarget> render_target_;
|
||||
|
||||
mutable bool cache_expired_;
|
||||
mutable ComPtr<ID2D1Bitmap> bitmap_cached_;
|
||||
};
|
||||
}
|
||||
|
|
@ -28,6 +28,11 @@
|
|||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace
|
||||
{
|
||||
bool show = false;
|
||||
}
|
||||
|
||||
DebugNode::DebugNode()
|
||||
{
|
||||
debug_text_ = new Text();
|
||||
|
|
@ -67,16 +72,14 @@ namespace easy2d
|
|||
|
||||
void DebugNode::OnRender()
|
||||
{
|
||||
auto& rt = RenderSystem::Instance();
|
||||
Renderer::Instance().GetSolidColorBrush()->SetColor(D2D1::ColorF(0.0f, 0.0f, 0.0f, 0.5f));
|
||||
|
||||
rt.GetSolidBrush()->SetColor(D2D1::ColorF(0.0f, 0.0f, 0.0f, 0.5f));
|
||||
|
||||
rt.GetRenderTarget()->FillRoundedRectangle(
|
||||
Renderer::Instance().GetDeviceResources()->GetD2DDeviceContext()->FillRoundedRectangle(
|
||||
D2D1::RoundedRect(
|
||||
D2D1_RECT_F{ 10, 10, 200, 120 },
|
||||
6.f,
|
||||
6.f),
|
||||
rt.GetSolidBrush().Get()
|
||||
Renderer::Instance().GetSolidColorBrush()
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -105,9 +108,9 @@ namespace easy2d
|
|||
ss << "Objects: " << Object::__GetTracingObjects().size() << std::endl;
|
||||
#endif
|
||||
|
||||
ss << "Render: " << RenderSystem::Instance().GetStatus().duration.Milliseconds() << "ms" << std::endl;
|
||||
ss << "Render: " << Renderer::Instance().GetStatus().duration.Milliseconds() << "ms" << std::endl;
|
||||
|
||||
ss << "Primitives / sec: " << RenderSystem::Instance().GetStatus().primitives * frame_time_.size() << std::endl;
|
||||
ss << "Primitives / sec: " << Renderer::Instance().GetStatus().primitives * frame_time_.size() << std::endl;
|
||||
|
||||
PROCESS_MEMORY_COUNTERS_EX pmc;
|
||||
GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc));
|
||||
|
|
@ -119,4 +122,19 @@ namespace easy2d
|
|||
debug_text_->SetText(ss.str());
|
||||
}
|
||||
|
||||
void DebugNode::Show()
|
||||
{
|
||||
show = true;
|
||||
}
|
||||
|
||||
void DebugNode::Hide()
|
||||
{
|
||||
show = false;
|
||||
}
|
||||
|
||||
bool DebugNode::IsShown()
|
||||
{
|
||||
return show;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
namespace easy2d
|
||||
{
|
||||
class E2D_API DebugNode
|
||||
: public Node
|
||||
: public VisualNode
|
||||
, public Singleton<DebugNode>
|
||||
{
|
||||
E2D_DECLARE_SINGLETON(DebugNode);
|
||||
|
|
@ -36,6 +36,12 @@ namespace easy2d
|
|||
|
||||
virtual ~DebugNode();
|
||||
|
||||
// 显示调试信息
|
||||
void Show();
|
||||
|
||||
// 隐藏调试信息
|
||||
void Hide();
|
||||
|
||||
void AddDebugText(String const& text);
|
||||
|
||||
void ClearDebugText();
|
||||
|
|
@ -44,6 +50,8 @@ namespace easy2d
|
|||
|
||||
void OnUpdate(Duration dt) override;
|
||||
|
||||
static bool IsShown();
|
||||
|
||||
protected:
|
||||
TextPtr debug_text_;
|
||||
Array<TimePoint> frame_time_;
|
||||
|
|
|
|||
|
|
@ -1,125 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - 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-forwards.h"
|
||||
#include "Singleton.hpp"
|
||||
#include "Font.hpp"
|
||||
#include "Resource.h"
|
||||
#include "TextRenderer.h"
|
||||
#include "TextStyle.hpp"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API Factory
|
||||
: public Singleton<Factory>
|
||||
{
|
||||
E2D_DECLARE_SINGLETON(Factory);
|
||||
|
||||
public:
|
||||
HRESULT Init(bool debug);
|
||||
|
||||
void Destroy();
|
||||
|
||||
HRESULT CreateHwndRenderTarget(
|
||||
_Out_ D2DHwndRenderTargetPtr& hwnd_render_target,
|
||||
D2D1_RENDER_TARGET_PROPERTIES const& properties,
|
||||
D2D1_HWND_RENDER_TARGET_PROPERTIES const& hwnd_rt_properties
|
||||
) const;
|
||||
|
||||
HRESULT CreateTextRenderer(
|
||||
_Out_ D2DTextRendererPtr& text_renderer,
|
||||
D2DRenderTargetPtr const& render_target,
|
||||
D2DSolidColorBrushPtr const& brush
|
||||
);
|
||||
|
||||
HRESULT CreateBitmapFromFile(
|
||||
_Out_ D2DBitmapPtr& bitmap,
|
||||
D2DRenderTargetPtr const& rt,
|
||||
String const& file_path
|
||||
);
|
||||
|
||||
HRESULT CreateBitmapFromResource(
|
||||
_Out_ D2DBitmapPtr& bitmap,
|
||||
D2DRenderTargetPtr const& rt,
|
||||
Resource const& res
|
||||
);
|
||||
|
||||
HRESULT CreateRectangleGeometry(
|
||||
_Out_ D2DRectangleGeometryPtr& geo,
|
||||
Rect const& rect
|
||||
) const;
|
||||
|
||||
HRESULT CreateRoundedRectangleGeometry(
|
||||
_Out_ D2DRoundedRectangleGeometryPtr& geo,
|
||||
Rect const& rect,
|
||||
float radius_x,
|
||||
float radius_y
|
||||
) const;
|
||||
|
||||
HRESULT CreateEllipseGeometry(
|
||||
_Out_ D2DEllipseGeometryPtr& geo,
|
||||
Point const& center,
|
||||
float radius_x,
|
||||
float radius_y
|
||||
) const;
|
||||
|
||||
HRESULT CreateTransformedGeometry(
|
||||
_Out_ D2DTransformedGeometryPtr& transformed,
|
||||
Matrix const& matrix,
|
||||
D2DGeometryPtr const& geo
|
||||
) const;
|
||||
|
||||
HRESULT CreatePathGeometry(
|
||||
_Out_ D2DPathGeometryPtr& geometry
|
||||
) const;
|
||||
|
||||
HRESULT CreateTextFormat(
|
||||
_Out_ D2DTextFormatPtr& text_format,
|
||||
Font const& font,
|
||||
TextStyle const& text_style
|
||||
) const;
|
||||
|
||||
HRESULT CreateTextLayout(
|
||||
_Out_ D2DTextLayoutPtr& text_layout,
|
||||
_Out_ Size& layout_size,
|
||||
String const& text,
|
||||
D2DTextFormatPtr const& text_format,
|
||||
TextStyle const& text_style
|
||||
) const;
|
||||
|
||||
D2DStrokeStylePtr const& GetStrokeStyle(
|
||||
StrokeStyle stroke
|
||||
) const;
|
||||
|
||||
protected:
|
||||
Factory();
|
||||
|
||||
~Factory();
|
||||
|
||||
protected:
|
||||
D2DFactoryPtr factory_;
|
||||
D2DImagingFactoryPtr imaging_factory_;
|
||||
D2DWriteFactoryPtr write_factory_;
|
||||
D2DStrokeStylePtr miter_stroke_style_;
|
||||
D2DStrokeStylePtr bevel_stroke_style_;
|
||||
D2DStrokeStylePtr round_stroke_style_;
|
||||
};
|
||||
}
|
||||
|
|
@ -19,7 +19,6 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#include "Geometry.h"
|
||||
#include "Factory.h"
|
||||
#include "render.h"
|
||||
#include "logs.h"
|
||||
|
||||
|
|
@ -99,7 +98,7 @@ namespace easy2d
|
|||
BOOL ret = 0;
|
||||
// no matter it failed or not
|
||||
geo_->FillContainsPoint(
|
||||
ToD2dPoint2F(point),
|
||||
DX::ConvertToPoint2F(point),
|
||||
D2D1::Matrix3x2F::Identity(),
|
||||
&ret
|
||||
);
|
||||
|
|
@ -126,10 +125,10 @@ namespace easy2d
|
|||
|
||||
void LineGeometry::SetLine(Point const & begin, Point const & end)
|
||||
{
|
||||
D2DPathGeometryPtr path_geo;
|
||||
D2DGeometrySinkPtr path_sink;
|
||||
ComPtr<ID2D1PathGeometry> path_geo;
|
||||
ComPtr<ID2D1GeometrySink> path_sink;
|
||||
|
||||
HRESULT hr = Factory::Instance().CreatePathGeometry(path_geo);
|
||||
HRESULT hr = Renderer::Instance().GetDeviceResources()->GetD2DFactory()->CreatePathGeometry(&path_geo);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
|
|
@ -138,8 +137,8 @@ namespace easy2d
|
|||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
path_sink->BeginFigure(ToD2dPoint2F(begin), D2D1_FIGURE_BEGIN_FILLED);
|
||||
path_sink->AddLine(ToD2dPoint2F(end));
|
||||
path_sink->BeginFigure(DX::ConvertToPoint2F(begin), D2D1_FIGURE_BEGIN_FILLED);
|
||||
path_sink->AddLine(DX::ConvertToPoint2F(end));
|
||||
path_sink->EndFigure(D2D1_FIGURE_END_OPEN);
|
||||
hr = path_sink->Close();
|
||||
}
|
||||
|
|
@ -185,8 +184,10 @@ namespace easy2d
|
|||
|
||||
void RectangleGeometry::SetRect(Rect const & rect)
|
||||
{
|
||||
D2DRectangleGeometryPtr geo;
|
||||
if (SUCCEEDED(Factory::Instance().CreateRectangleGeometry(geo, rect)))
|
||||
ComPtr<ID2D1RectangleGeometry> geo;
|
||||
auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory();
|
||||
|
||||
if (SUCCEEDED(factory->CreateRectangleGeometry(DX::ConvertToRectF(rect), &geo)))
|
||||
{
|
||||
geo_ = geo;
|
||||
rect_ = rect;
|
||||
|
|
@ -224,8 +225,15 @@ namespace easy2d
|
|||
|
||||
void CircleGeometry::SetCircle(Point const & center, float radius)
|
||||
{
|
||||
D2DEllipseGeometryPtr geo;
|
||||
if (SUCCEEDED(Factory::Instance().CreateEllipseGeometry(geo, center, radius, radius)))
|
||||
ComPtr<ID2D1EllipseGeometry> geo;
|
||||
auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory();
|
||||
|
||||
if (SUCCEEDED(factory->CreateEllipseGeometry(
|
||||
D2D1::Ellipse(
|
||||
DX::ConvertToPoint2F(center),
|
||||
radius,
|
||||
radius),
|
||||
&geo)))
|
||||
{
|
||||
geo_ = geo;
|
||||
center_ = center;
|
||||
|
|
@ -265,8 +273,15 @@ namespace easy2d
|
|||
|
||||
void EllipseGeometry::SetEllipse(Point const & center, float radius_x, float radius_y)
|
||||
{
|
||||
D2DEllipseGeometryPtr geo;
|
||||
if (SUCCEEDED(Factory::Instance().CreateEllipseGeometry(geo, center, radius_x, radius_y)))
|
||||
ComPtr<ID2D1EllipseGeometry> geo;
|
||||
auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory();
|
||||
|
||||
if (SUCCEEDED(factory->CreateEllipseGeometry(
|
||||
D2D1::Ellipse(
|
||||
DX::ConvertToPoint2F(center),
|
||||
radius_x,
|
||||
radius_y),
|
||||
&geo)))
|
||||
{
|
||||
geo_ = geo;
|
||||
radius_x_ = radius_x;
|
||||
|
|
@ -291,15 +306,17 @@ namespace easy2d
|
|||
{
|
||||
current_geometry_ = nullptr;
|
||||
|
||||
auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory();
|
||||
|
||||
ThrowIfFailed(
|
||||
Factory::Instance().CreatePathGeometry(current_geometry_)
|
||||
factory->CreatePathGeometry(¤t_geometry_)
|
||||
);
|
||||
|
||||
ThrowIfFailed(
|
||||
current_geometry_->Open(¤t_sink_)
|
||||
);
|
||||
|
||||
current_sink_->BeginFigure(ToD2dPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED);
|
||||
current_sink_->BeginFigure(DX::ConvertToPoint2F(begin_pos), D2D1_FIGURE_BEGIN_FILLED);
|
||||
}
|
||||
|
||||
void PathGeometry::EndPath(bool closed)
|
||||
|
|
@ -321,7 +338,7 @@ namespace easy2d
|
|||
void PathGeometry::AddLine(Point const & point)
|
||||
{
|
||||
if (current_sink_)
|
||||
current_sink_->AddLine(ToD2dPoint2F(point));
|
||||
current_sink_->AddLine(DX::ConvertToPoint2F(point));
|
||||
}
|
||||
|
||||
void PathGeometry::AddLines(Array<Point> const& points)
|
||||
|
|
@ -341,9 +358,9 @@ namespace easy2d
|
|||
{
|
||||
current_sink_->AddBezier(
|
||||
D2D1::BezierSegment(
|
||||
ToD2dPoint2F(point1),
|
||||
ToD2dPoint2F(point2),
|
||||
ToD2dPoint2F(point3)
|
||||
DX::ConvertToPoint2F(point1),
|
||||
DX::ConvertToPoint2F(point2),
|
||||
DX::ConvertToPoint2F(point3)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
@ -355,8 +372,8 @@ namespace easy2d
|
|||
{
|
||||
current_sink_->AddArc(
|
||||
D2D1::ArcSegment(
|
||||
ToD2dPoint2F(point),
|
||||
ToD2dSizeF(radius),
|
||||
DX::ConvertToPoint2F(point),
|
||||
DX::ConvertToSizeF(radius),
|
||||
rotation,
|
||||
clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,
|
||||
is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE
|
||||
|
|
@ -404,8 +421,16 @@ namespace easy2d
|
|||
|
||||
void RoundedRectGeometry::SetRoundedRect(Rect const & rect, float radius_x, float radius_y)
|
||||
{
|
||||
D2DRoundedRectangleGeometryPtr geo;
|
||||
if (SUCCEEDED(Factory::Instance().CreateRoundedRectangleGeometry(geo, rect, radius_x, radius_y)))
|
||||
ComPtr<ID2D1RoundedRectangleGeometry> geo;
|
||||
auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory();
|
||||
|
||||
if (SUCCEEDED(factory->CreateRoundedRectangleGeometry(
|
||||
D2D1::RoundedRect(
|
||||
DX::ConvertToRectF(rect),
|
||||
radius_x,
|
||||
radius_y
|
||||
),
|
||||
&geo)))
|
||||
{
|
||||
geo_ = geo;
|
||||
rect_ = rect;
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ namespace easy2d
|
|||
float ComputeArea();
|
||||
|
||||
protected:
|
||||
D2DGeometryPtr geo_;
|
||||
ComPtr<ID2D1Geometry> geo_;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -254,8 +254,8 @@ namespace easy2d
|
|||
void ClearPath();
|
||||
|
||||
protected:
|
||||
D2DPathGeometryPtr current_geometry_;
|
||||
D2DGeometrySinkPtr current_sink_;
|
||||
ComPtr<ID2D1PathGeometry> current_geometry_;
|
||||
ComPtr<ID2D1GeometrySink> current_sink_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -70,14 +70,12 @@ namespace easy2d
|
|||
{
|
||||
if (geometry_ && geometry_->geo_)
|
||||
{
|
||||
auto& rt = RenderSystem::Instance();
|
||||
|
||||
rt.FillGeometry(
|
||||
geometry_->geo_,
|
||||
Renderer::Instance().FillGeometry(
|
||||
geometry_->geo_.Get(),
|
||||
fill_color_
|
||||
);
|
||||
|
||||
rt.DrawGeometry(
|
||||
Renderer::Instance().DrawGeometry(
|
||||
geometry_->geo_,
|
||||
stroke_color_,
|
||||
stroke_width_,
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace easy2d
|
|||
{
|
||||
// 섯부暠近
|
||||
class E2D_API GeometryNode
|
||||
: public Node
|
||||
: public VisualNode
|
||||
{
|
||||
public:
|
||||
GeometryNode();
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#include "Image.h"
|
||||
#include "render.h"
|
||||
#include "logs.h"
|
||||
#include "render.h"
|
||||
#include "../utils/File.h"
|
||||
#include "../utils/string.h"
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ namespace easy2d
|
|||
this->Crop(crop_rect);
|
||||
}
|
||||
|
||||
Image::Image(D2DBitmapPtr const & bitmap)
|
||||
Image::Image(ComPtr<ID2D1Bitmap> const & bitmap)
|
||||
: Image()
|
||||
{
|
||||
SetBitmap(bitmap);
|
||||
|
|
@ -58,7 +58,7 @@ namespace easy2d
|
|||
bool Image::Load(Resource const& res)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
D2DBitmapPtr bitmap;
|
||||
ComPtr<ID2D1Bitmap> bitmap;
|
||||
|
||||
if (res.IsFileType())
|
||||
{
|
||||
|
|
@ -67,11 +67,11 @@ namespace easy2d
|
|||
E2D_WARNING_LOG(L"Image file '%s' not found!", res.GetFileName().c_str());
|
||||
return false;
|
||||
}
|
||||
hr = RenderSystem::Instance().CreateBitmapFromFile(bitmap, res.GetFileName());
|
||||
hr = Renderer::Instance().GetDeviceResources()->CreateBitmapFromFile(bitmap, res.GetFileName());
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = RenderSystem::Instance().CreateBitmapFromResource(bitmap, res);
|
||||
hr = Renderer::Instance().GetDeviceResources()->CreateBitmapFromResource(bitmap, res);
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
|
|
@ -164,12 +164,12 @@ namespace easy2d
|
|||
return crop_rect_;
|
||||
}
|
||||
|
||||
D2DBitmapPtr const& Image::GetBitmap() const
|
||||
ComPtr<ID2D1Bitmap> const& Image::GetBitmap() const
|
||||
{
|
||||
return bitmap_;
|
||||
}
|
||||
|
||||
void Image::SetBitmap(D2DBitmapPtr const & bitmap)
|
||||
void Image::SetBitmap(ComPtr<ID2D1Bitmap> const & bitmap)
|
||||
{
|
||||
if (bitmap)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ namespace easy2d
|
|||
);
|
||||
|
||||
explicit Image(
|
||||
D2DBitmapPtr const& bitmap
|
||||
ComPtr<ID2D1Bitmap> const& bitmap
|
||||
);
|
||||
|
||||
virtual ~Image();
|
||||
|
|
@ -89,15 +89,15 @@ namespace easy2d
|
|||
// »ñÈ¡²Ã¼ô¾ØÐÎ
|
||||
Rect const& GetCropRect() const;
|
||||
|
||||
D2DBitmapPtr const& GetBitmap() const;
|
||||
ComPtr<ID2D1Bitmap> const& GetBitmap() const;
|
||||
|
||||
protected:
|
||||
void SetBitmap(
|
||||
D2DBitmapPtr const& bitmap
|
||||
ComPtr<ID2D1Bitmap> const& bitmap
|
||||
);
|
||||
|
||||
protected:
|
||||
Rect crop_rect_;
|
||||
D2DBitmapPtr bitmap_;
|
||||
ComPtr<ID2D1Bitmap> bitmap_;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,10 +37,8 @@ namespace easy2d
|
|||
{
|
||||
}
|
||||
|
||||
HRESULT Input::Init(HWND hwnd, bool debug)
|
||||
HRESULT Input::Init(HWND hwnd)
|
||||
{
|
||||
E2D_NOT_USED(debug);
|
||||
|
||||
hwnd_ = hwnd;
|
||||
|
||||
return S_OK;
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ namespace easy2d
|
|||
// 資誼報炎恫炎
|
||||
Point GetMousePos();
|
||||
|
||||
HRESULT Init(HWND hwnd, bool debug);
|
||||
HRESULT Init(HWND hwnd);
|
||||
|
||||
void Update();
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
#include "Node.h"
|
||||
#include "Action.h"
|
||||
#include "Factory.h"
|
||||
#include "Scene.h"
|
||||
#include "Task.h"
|
||||
#include "render.h"
|
||||
|
|
@ -42,7 +41,7 @@ namespace easy2d
|
|||
|
||||
Node::Node()
|
||||
: visible_(true)
|
||||
, pause_(false)
|
||||
, update_pausing_(false)
|
||||
, hover_(false)
|
||||
, pressed_(false)
|
||||
, responsible_(false)
|
||||
|
|
@ -59,7 +58,7 @@ namespace easy2d
|
|||
|
||||
void Node::Update(Duration dt)
|
||||
{
|
||||
if (pause_)
|
||||
if (update_pausing_)
|
||||
return;
|
||||
|
||||
UpdateActions(this, dt);
|
||||
|
|
@ -88,13 +87,9 @@ namespace easy2d
|
|||
|
||||
UpdateTransform();
|
||||
|
||||
auto& rt = RenderSystem::Instance();
|
||||
|
||||
if (children_.IsEmpty())
|
||||
{
|
||||
rt.SetTransform(transform_matrix_);
|
||||
rt.SetOpacity(display_opacity_);
|
||||
|
||||
PrepareRender();
|
||||
OnRender();
|
||||
}
|
||||
else
|
||||
|
|
@ -110,9 +105,7 @@ namespace easy2d
|
|||
child = child->NextItem().Get();
|
||||
}
|
||||
|
||||
rt.SetTransform(transform_matrix_);
|
||||
rt.SetOpacity(display_opacity_);
|
||||
|
||||
PrepareRender();
|
||||
OnRender();
|
||||
|
||||
while (child)
|
||||
|
|
@ -184,16 +177,6 @@ namespace easy2d
|
|||
EventDispatcher::Dispatch(evt);
|
||||
}
|
||||
|
||||
void Node::PauseUpdating()
|
||||
{
|
||||
pause_ = true;
|
||||
}
|
||||
|
||||
void Node::ResumeUpdating()
|
||||
{
|
||||
pause_ = false;
|
||||
}
|
||||
|
||||
Matrix const & Node::GetTransformMatrix() const
|
||||
{
|
||||
UpdateTransform();
|
||||
|
|
@ -607,4 +590,12 @@ namespace easy2d
|
|||
Point local = GetTransformInverseMatrix().Transform(point);
|
||||
return GetBounds().ContainsPoint(local);
|
||||
}
|
||||
|
||||
|
||||
void VisualNode::PrepareRender()
|
||||
{
|
||||
Renderer::Instance().SetTransform(transform_matrix_);
|
||||
Renderer::Instance().SetOpacity(display_opacity_);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -344,13 +344,13 @@ namespace easy2d
|
|||
void RemoveFromParent();
|
||||
|
||||
// 暂停节点更新
|
||||
void PauseUpdating();
|
||||
inline void PauseUpdating() { update_pausing_ = true; }
|
||||
|
||||
// 继续节点更新
|
||||
void ResumeUpdating();
|
||||
inline void ResumeUpdating() { update_pausing_ = false; }
|
||||
|
||||
// 节点更新是否暂停
|
||||
inline bool IsUpdatePausing() const { return pause_; }
|
||||
inline bool IsUpdatePausing() const { return update_pausing_; }
|
||||
|
||||
// 设置更新时的回调函数
|
||||
inline void SetCallbackOnUpdate(UpdateCallback const& cb) { cb_update_ = cb; }
|
||||
|
|
@ -365,6 +365,8 @@ namespace easy2d
|
|||
);
|
||||
|
||||
protected:
|
||||
virtual void PrepareRender() {}
|
||||
|
||||
void Update(Duration dt);
|
||||
|
||||
void Render();
|
||||
|
|
@ -380,7 +382,7 @@ namespace easy2d
|
|||
bool hover_;
|
||||
bool pressed_;
|
||||
bool responsible_;
|
||||
bool pause_;
|
||||
bool update_pausing_;
|
||||
int z_order_;
|
||||
float opacity_;
|
||||
float display_opacity_;
|
||||
|
|
@ -398,4 +400,13 @@ namespace easy2d
|
|||
mutable Matrix transform_matrix_;
|
||||
mutable Matrix transform_matrix_inverse_;
|
||||
};
|
||||
|
||||
|
||||
class E2D_API VisualNode
|
||||
: public Node
|
||||
{
|
||||
public:
|
||||
virtual void PrepareRender() override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ namespace easy2d
|
|||
{
|
||||
// ³¡¾°
|
||||
class E2D_API Scene
|
||||
: public Node
|
||||
: public VisualNode
|
||||
{
|
||||
public:
|
||||
Scene();
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ namespace easy2d
|
|||
{
|
||||
if (image_)
|
||||
{
|
||||
RenderSystem::Instance().DrawImage(image_, GetBounds());
|
||||
Renderer::Instance().DrawImage(image_, GetBounds());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ namespace easy2d
|
|||
{
|
||||
// ¾«Áé
|
||||
class E2D_API Sprite
|
||||
: public Node
|
||||
: public VisualNode
|
||||
{
|
||||
public:
|
||||
Sprite();
|
||||
|
|
|
|||
|
|
@ -19,9 +19,7 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#include "Text.h"
|
||||
#include "Factory.h"
|
||||
#include "render.h"
|
||||
#include "include-forwards.h"
|
||||
#include "logs.h"
|
||||
|
||||
namespace easy2d
|
||||
|
|
@ -45,6 +43,7 @@ namespace easy2d
|
|||
Text::Text()
|
||||
: font_(text_default_font)
|
||||
, style_(text_default_style)
|
||||
, layout_dirty_(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -67,8 +66,8 @@ namespace easy2d
|
|||
: font_(font)
|
||||
, style_(style)
|
||||
, text_(text)
|
||||
, layout_dirty_(true)
|
||||
{
|
||||
UpdateLayout();
|
||||
}
|
||||
|
||||
Text::~Text()
|
||||
|
|
@ -127,6 +126,7 @@ namespace easy2d
|
|||
|
||||
int Text::GetLineCount()
|
||||
{
|
||||
UpdateLayout();
|
||||
if (text_layout_)
|
||||
{
|
||||
DWRITE_TEXT_METRICS metrics;
|
||||
|
|
@ -138,6 +138,12 @@ namespace easy2d
|
|||
return 0;
|
||||
}
|
||||
|
||||
Size const& Text::GetLayoutSize() const
|
||||
{
|
||||
UpdateLayout();
|
||||
return layout_size_;
|
||||
}
|
||||
|
||||
bool Text::IsItalic() const
|
||||
{
|
||||
return font_.italic;
|
||||
|
|
@ -161,19 +167,19 @@ namespace easy2d
|
|||
void Text::SetText(String const& text)
|
||||
{
|
||||
text_ = text;
|
||||
UpdateLayout();
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
|
||||
void Text::SetStyle(const TextStyle& style)
|
||||
{
|
||||
style_ = style;
|
||||
UpdateLayout();
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
|
||||
void Text::SetFont(const Font & font)
|
||||
{
|
||||
font_ = font;
|
||||
UpdateLayout();
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
|
||||
void Text::SetFontFamily(String const& family)
|
||||
|
|
@ -181,7 +187,7 @@ namespace easy2d
|
|||
if (font_.family != family)
|
||||
{
|
||||
font_.family = family;
|
||||
UpdateLayout();
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -190,7 +196,7 @@ namespace easy2d
|
|||
if (font_.size != size)
|
||||
{
|
||||
font_.size = size;
|
||||
UpdateLayout();
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -199,7 +205,7 @@ namespace easy2d
|
|||
if (font_.weight != weight)
|
||||
{
|
||||
font_.weight = weight;
|
||||
UpdateLayout();
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -213,7 +219,7 @@ namespace easy2d
|
|||
if (font_.italic != val)
|
||||
{
|
||||
font_.italic = val;
|
||||
UpdateLayout();
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -222,7 +228,7 @@ namespace easy2d
|
|||
if (style_.wrap != wrap)
|
||||
{
|
||||
style_.wrap = wrap;
|
||||
UpdateLayout();
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -231,7 +237,7 @@ namespace easy2d
|
|||
if (style_.wrap_width != wrap_width)
|
||||
{
|
||||
style_.wrap_width = std::max(wrap_width, 0.f);
|
||||
UpdateLayout();
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +246,7 @@ namespace easy2d
|
|||
if (style_.line_spacing != line_spacing)
|
||||
{
|
||||
style_.line_spacing = line_spacing;
|
||||
UpdateLayout();
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -249,7 +255,7 @@ namespace easy2d
|
|||
if (style_.alignment != align)
|
||||
{
|
||||
style_.alignment = align;
|
||||
UpdateLayout();
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -258,7 +264,7 @@ namespace easy2d
|
|||
if (style_.underline != underline)
|
||||
{
|
||||
style_.underline = underline;
|
||||
UpdateLayout();
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -267,7 +273,7 @@ namespace easy2d
|
|||
if (style_.strikethrough != strikethrough)
|
||||
{
|
||||
style_.strikethrough = strikethrough;
|
||||
UpdateLayout();
|
||||
layout_dirty_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -293,22 +299,27 @@ namespace easy2d
|
|||
|
||||
void Text::OnRender()
|
||||
{
|
||||
UpdateLayout();
|
||||
|
||||
if (text_layout_)
|
||||
{
|
||||
auto& rt = RenderSystem::Instance();
|
||||
rt.SetTextStyle(
|
||||
Renderer::Instance().SetTextStyle(
|
||||
style_.color,
|
||||
style_.outline,
|
||||
style_.outline_color,
|
||||
style_.outline_width,
|
||||
style_.outline_stroke
|
||||
);
|
||||
rt.DrawTextLayout(text_layout_);
|
||||
Renderer::Instance().DrawTextLayout(text_layout_);
|
||||
}
|
||||
}
|
||||
|
||||
void Text::UpdateLayout()
|
||||
void Text::UpdateLayout() const
|
||||
{
|
||||
if (!layout_dirty_)
|
||||
return;
|
||||
|
||||
layout_dirty_ = false;
|
||||
text_format_ = nullptr;
|
||||
text_layout_ = nullptr;
|
||||
|
||||
|
|
@ -316,24 +327,21 @@ namespace easy2d
|
|||
return;
|
||||
|
||||
ThrowIfFailed(
|
||||
Factory::Instance().CreateTextFormat(
|
||||
Renderer::Instance().GetDeviceResources()->CreateTextFormat(
|
||||
text_format_,
|
||||
font_,
|
||||
style_
|
||||
)
|
||||
);
|
||||
|
||||
Size layout_size;
|
||||
ThrowIfFailed(
|
||||
Factory::Instance().CreateTextLayout(
|
||||
Renderer::Instance().GetDeviceResources()->CreateTextLayout(
|
||||
text_layout_,
|
||||
layout_size,
|
||||
layout_size_,
|
||||
text_,
|
||||
text_format_,
|
||||
style_
|
||||
)
|
||||
);
|
||||
|
||||
this->SetSize(layout_size);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace easy2d
|
|||
{
|
||||
// 文本
|
||||
class E2D_API Text
|
||||
: public Node
|
||||
: public VisualNode
|
||||
{
|
||||
public:
|
||||
Text();
|
||||
|
|
@ -87,6 +87,9 @@ namespace easy2d
|
|||
// 获取文本显示行数
|
||||
int GetLineCount();
|
||||
|
||||
// 获取文字布局大小
|
||||
Size const& GetLayoutSize() const;
|
||||
|
||||
// 是否是斜体
|
||||
bool IsItalic() const;
|
||||
|
||||
|
|
@ -202,13 +205,16 @@ namespace easy2d
|
|||
void OnRender() override;
|
||||
|
||||
protected:
|
||||
void UpdateLayout();
|
||||
void UpdateLayout() const;
|
||||
|
||||
protected:
|
||||
String text_;
|
||||
Font font_;
|
||||
TextStyle style_;
|
||||
D2DTextFormatPtr text_format_;
|
||||
D2DTextLayoutPtr text_layout_;
|
||||
String text_;
|
||||
Font font_;
|
||||
TextStyle style_;
|
||||
|
||||
mutable bool layout_dirty_;
|
||||
mutable Size layout_size_;
|
||||
mutable ComPtr<IDWriteTextFormat> text_format_;
|
||||
mutable ComPtr<IDWriteTextLayout> text_layout_;
|
||||
};
|
||||
}
|
||||
|
|
@ -19,11 +19,11 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "helper.hpp"
|
||||
#include "../math/Matrix.hpp"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API Transform
|
||||
class Transform
|
||||
{
|
||||
public:
|
||||
float rotation; // Ðýת
|
||||
|
|
|
|||
|
|
@ -66,14 +66,14 @@ namespace easy2d
|
|||
if (in_scene_)
|
||||
{
|
||||
ThrowIfFailed(
|
||||
RenderSystem::Instance().CreateLayer(in_layer_)
|
||||
Renderer::Instance().CreateLayer(in_layer_)
|
||||
);
|
||||
}
|
||||
|
||||
if (out_scene_)
|
||||
{
|
||||
ThrowIfFailed(
|
||||
RenderSystem::Instance().CreateLayer(out_layer_)
|
||||
Renderer::Instance().CreateLayer(out_layer_)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -101,34 +101,34 @@ namespace easy2d
|
|||
|
||||
void Transition::Render()
|
||||
{
|
||||
auto& rt = RenderSystem::Instance();
|
||||
auto& renderer = Renderer::Instance();
|
||||
|
||||
if (out_scene_)
|
||||
{
|
||||
rt.PushClip(
|
||||
renderer.PushClip(
|
||||
out_scene_->GetTransformMatrix(),
|
||||
window_size_
|
||||
);
|
||||
rt.PushLayer(out_layer_, out_layer_prop_);
|
||||
renderer.PushLayer(out_layer_, out_layer_prop_);
|
||||
|
||||
out_scene_->Render();
|
||||
|
||||
rt.PopLayer();
|
||||
rt.PopClip();
|
||||
renderer.PopLayer();
|
||||
renderer.PopClip();
|
||||
}
|
||||
|
||||
if (in_scene_)
|
||||
{
|
||||
rt.PushClip(
|
||||
renderer.PushClip(
|
||||
in_scene_->GetTransformMatrix(),
|
||||
window_size_
|
||||
);
|
||||
rt.PushLayer(in_layer_, in_layer_prop_);
|
||||
renderer.PushLayer(in_layer_, in_layer_prop_);
|
||||
|
||||
in_scene_->Render();
|
||||
|
||||
rt.PopLayer();
|
||||
rt.PopClip();
|
||||
renderer.PopLayer();
|
||||
renderer.PopClip();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,8 +63,8 @@ namespace easy2d
|
|||
Size window_size_;
|
||||
ScenePtr out_scene_;
|
||||
ScenePtr in_scene_;
|
||||
D2DLayerPtr out_layer_;
|
||||
D2DLayerPtr in_layer_;
|
||||
ComPtr<ID2D1Layer> out_layer_;
|
||||
ComPtr<ID2D1Layer> in_layer_;
|
||||
LayerProperties out_layer_prop_;
|
||||
LayerProperties in_layer_prop_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -169,10 +169,8 @@ namespace easy2d
|
|||
{
|
||||
}
|
||||
|
||||
HRESULT Audio::Init(bool debug)
|
||||
HRESULT Audio::Init()
|
||||
{
|
||||
E2D_NOT_USED(debug);
|
||||
|
||||
E2D_LOG(L"Initing audio resources");
|
||||
|
||||
HRESULT hr = modules::MediaFoundation::Get().MFStartup(MF_VERSION, MFSTARTUP_FULL);
|
||||
|
|
@ -202,7 +200,7 @@ namespace easy2d
|
|||
mastering_voice_ = nullptr;
|
||||
}
|
||||
|
||||
SafeRelease(x_audio2_);
|
||||
DX::SafeRelease(x_audio2_);
|
||||
|
||||
modules::MediaFoundation::Get().MFShutdown();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ namespace easy2d
|
|||
using VoiceMap = UnorderedSet<Voice*>;
|
||||
|
||||
public:
|
||||
HRESULT Init(bool debug);
|
||||
HRESULT Init();
|
||||
|
||||
void Destroy();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,101 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - 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 "IntrusivePtr.hpp"
|
||||
#include "../math/vector.hpp"
|
||||
#include "../math/Rect.hpp"
|
||||
#include "Color.h"
|
||||
#include <d2d1.h>
|
||||
#include <dwrite.h>
|
||||
|
||||
#ifndef E2D_DECLARE_D2D_SMART_PTR
|
||||
#define E2D_DECLARE_D2D_SMART_PTR(class_name, sp_name)\
|
||||
using sp_name = ::easy2d::IntrusivePtr< class_name >
|
||||
#endif
|
||||
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// "D2DPtr" is a shorthand for "COM Pointer"
|
||||
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1Factory, D2DFactoryPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(IWICImagingFactory, D2DImagingFactoryPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(IDWriteFactory, D2DWriteFactoryPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1SolidColorBrush, D2DSolidColorBrushPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1RenderTarget, D2DRenderTargetPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1HwndRenderTarget, D2DHwndRenderTargetPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1BitmapRenderTarget, D2DBitmapRenderTargetPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1StrokeStyle, D2DStrokeStylePtr);
|
||||
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1Geometry, D2DGeometryPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1RectangleGeometry, D2DRectangleGeometryPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1RoundedRectangleGeometry, D2DRoundedRectangleGeometryPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1EllipseGeometry, D2DEllipseGeometryPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1GeometryGroup, D2DGeometryGroupPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1PathGeometry, D2DPathGeometryPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1TransformedGeometry, D2DTransformedGeometryPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1GeometrySink, D2DGeometrySinkPtr);
|
||||
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1Layer, D2DLayerPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(ID2D1Bitmap, D2DBitmapPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(IDWriteTextFormat, D2DTextFormatPtr);
|
||||
E2D_DECLARE_D2D_SMART_PTR(IDWriteTextLayout, D2DTextLayoutPtr);
|
||||
|
||||
inline void IntrusivePtrAddRef(IUnknown* ptr)
|
||||
{
|
||||
if (ptr) { ptr->AddRef(); }
|
||||
}
|
||||
|
||||
inline void IntrusivePtrRelease(IUnknown* ptr)
|
||||
{
|
||||
if (ptr) { ptr->Release(); }
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void SafeRelease(T*& ptr)
|
||||
{
|
||||
if (ptr != nullptr)
|
||||
{
|
||||
ptr->Release();
|
||||
ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
inline D2D1_POINT_2F const& ToD2dPoint2F(math::Vec2 const& point)
|
||||
{
|
||||
return reinterpret_cast<D2D1_POINT_2F const&>(point);
|
||||
}
|
||||
|
||||
inline D2D1_SIZE_F const& ToD2dSizeF(math::Vec2 const& size)
|
||||
{
|
||||
return reinterpret_cast<D2D1_SIZE_F const&>(size);
|
||||
}
|
||||
|
||||
inline D2D1_RECT_F ToD2dRectF(math::Rect const& rect)
|
||||
{
|
||||
return D2D1_RECT_F{ rect.origin.x, rect.origin.y, rect.origin.x + rect.size.x, rect.origin.y + rect.size.y };
|
||||
}
|
||||
|
||||
inline D2D1_COLOR_F const& ToD2dColorF(Color const& color)
|
||||
{
|
||||
return reinterpret_cast<D2D1_COLOR_F const&>(color);
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@
|
|||
#include "closure.hpp"
|
||||
#include "../math/vector.hpp"
|
||||
#include "../math/Rect.hpp"
|
||||
#include "../math/Matrix.h"
|
||||
#include "../math/Matrix.hpp"
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
|
@ -72,8 +72,6 @@ namespace easy2d
|
|||
|
||||
namespace easy2d
|
||||
{
|
||||
// "Ptr" is a shorthand for "Smart Pointer"
|
||||
|
||||
E2D_DECLARE_SMART_PTR(Object);
|
||||
E2D_DECLARE_SMART_PTR(Image);
|
||||
E2D_DECLARE_SMART_PTR(Music);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
#include "Color.h"
|
||||
#include "Object.h"
|
||||
#include "helper.hpp"
|
||||
#include "d2dhelper.hpp"
|
||||
#include "../DX/helper.hpp"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
|
|
|||
|
|
@ -97,7 +97,10 @@ namespace easy2d
|
|||
if (FAILED(hr))
|
||||
{
|
||||
E2D_ERROR_LOG(L"Fatal error with HRESULT of %08X", hr);
|
||||
throw std::runtime_error("Fatal error");
|
||||
|
||||
static char buffer[1024 + 1];
|
||||
sprintf_s(buffer, "Fatal error with HRESULT of %08X", hr);
|
||||
throw std::runtime_error(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,17 @@ namespace easy2d
|
|||
{
|
||||
E2D_LOG(L"load dwrite.dll failed");
|
||||
}
|
||||
|
||||
d3d11 = LoadLibraryW(L"d3d11.dll");
|
||||
if (d3d11)
|
||||
{
|
||||
D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)
|
||||
GetProcAddress(d3d11, "D3D11CreateDevice");
|
||||
}
|
||||
else
|
||||
{
|
||||
E2D_LOG(L"load d3d11.dll failed");
|
||||
}
|
||||
}
|
||||
|
||||
XAudio2::XAudio2()
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <mfapi.h>
|
||||
#include <mfidl.h>
|
||||
#include <mfreadwrite.h>
|
||||
#include <d3d11.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
|
@ -57,6 +58,7 @@ namespace easy2d
|
|||
{
|
||||
DirectX();
|
||||
|
||||
HMODULE d3d11;
|
||||
HMODULE d2d;
|
||||
HMODULE dwrite;
|
||||
|
||||
|
|
@ -73,6 +75,7 @@ namespace easy2d
|
|||
|
||||
PFN_D2D1CreateFactory D2D1CreateFactory;
|
||||
PFN_DWriteCreateFactory DWriteCreateFactory;
|
||||
PFN_D3D11_CREATE_DEVICE D3D11CreateDevice;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -20,220 +20,233 @@
|
|||
|
||||
#include "render.h"
|
||||
#include "logs.h"
|
||||
#include "Factory.h"
|
||||
#include "render.h"
|
||||
#include "Image.h"
|
||||
#include "Transform.hpp"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
RenderSystem::RenderSystem()
|
||||
: fps_text_format_(nullptr)
|
||||
, fps_text_layout_(nullptr)
|
||||
Renderer::Renderer()
|
||||
: antialias_(true)
|
||||
, text_antialias_(TextAntialias::ClearType)
|
||||
, clear_color_(D2D1::ColorF(D2D1::ColorF::Black))
|
||||
, opacity_(1.f)
|
||||
, debug_(false)
|
||||
, window_occluded_(false)
|
||||
, vsync_enabled_(true)
|
||||
, antialias_(true)
|
||||
, text_antialias_(TextAntialias::ClearType)
|
||||
{
|
||||
status_.primitives = 0;
|
||||
}
|
||||
|
||||
Renderer::~Renderer()
|
||||
{
|
||||
}
|
||||
|
||||
RenderSystem::~RenderSystem()
|
||||
HRESULT Renderer::Init(HWND hwnd)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
E2D_LOG(L"Creating device resources");
|
||||
|
||||
{
|
||||
device_resources_ = nullptr;
|
||||
hr = DeviceResources::Create(
|
||||
&device_resources_,
|
||||
hwnd
|
||||
);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
factory_ = device_resources_->GetD2DFactory();
|
||||
device_context_ = device_resources_->GetD2DDeviceContext();
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
drawing_state_block_ = nullptr;
|
||||
hr = factory_->CreateDrawingStateBlock(
|
||||
&drawing_state_block_
|
||||
);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = CreateDeviceResources();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::Init(HWND hwnd, bool vsync, bool debug)
|
||||
void Renderer::Destroy()
|
||||
{
|
||||
E2D_LOG(L"Initing graphics resources");
|
||||
|
||||
vsync_enabled_ = vsync;
|
||||
debug_ = debug;
|
||||
|
||||
return CreateResources(hwnd);
|
||||
}
|
||||
|
||||
void RenderSystem::Destroy()
|
||||
{
|
||||
E2D_LOG(L"Destroying graphics resources");
|
||||
|
||||
ClearImageCache();
|
||||
E2D_LOG(L"Destroying device resources");
|
||||
|
||||
device_resources_.Reset();
|
||||
factory_.Reset();
|
||||
device_context_.Reset();
|
||||
drawing_state_block_.Reset();
|
||||
text_renderer_.Reset();
|
||||
solid_brush_.Reset();
|
||||
render_target_.Reset();
|
||||
fps_text_format_.Reset();
|
||||
fps_text_layout_.Reset();
|
||||
solid_color_brush_.Reset();
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::BeginDraw(HWND hwnd)
|
||||
HRESULT Renderer::CreateDeviceResources()
|
||||
{
|
||||
HRESULT hr = CreateResources(hwnd);
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (debug_)
|
||||
hr = device_context_->CreateSolidColorBrush(
|
||||
D2D1::ColorF(D2D1::ColorF::White),
|
||||
&solid_color_brush_
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = ITextRenderer::Create(
|
||||
&text_renderer_,
|
||||
device_context_.Get()
|
||||
);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
SetAntialiasMode(antialias_);
|
||||
SetTextAntialiasMode(text_antialias_);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Renderer::HandleDeviceLost()
|
||||
{
|
||||
HRESULT hr = device_resources_->HandleDeviceLost();
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = CreateDeviceResources();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Renderer::BeginDraw()
|
||||
{
|
||||
if (!device_context_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
// if (debug_)
|
||||
{
|
||||
status_.start = time::Now();
|
||||
status_.primitives = 0;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
window_occluded_ = !!(render_target_->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED);
|
||||
device_context_->SaveDrawingState(drawing_state_block_.Get());
|
||||
|
||||
if (!window_occluded_)
|
||||
{
|
||||
render_target_->BeginDraw();
|
||||
render_target_->Clear(clear_color_);
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
device_context_->BeginDraw();
|
||||
device_context_->Clear(clear_color_);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::EndDraw()
|
||||
HRESULT Renderer::EndDraw()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (!window_occluded_)
|
||||
{
|
||||
hr = render_target_->EndDraw();
|
||||
if (!device_context_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (hr == D2DERR_RECREATE_TARGET)
|
||||
{
|
||||
// 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源
|
||||
// 并在下一次调用时重建资源
|
||||
DiscardResources();
|
||||
hr = S_OK;
|
||||
}
|
||||
HRESULT hr = device_context_->EndDraw();
|
||||
|
||||
device_context_->RestoreDrawingState(drawing_state_block_.Get());
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// The first argument instructs DXGI to block until VSync.
|
||||
hr = device_resources_->GetDXGISwapChain()->Present(1, 0);
|
||||
}
|
||||
|
||||
if (debug_)
|
||||
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
|
||||
{
|
||||
// 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源
|
||||
hr = HandleDeviceLost();
|
||||
}
|
||||
|
||||
// if (debug_)
|
||||
{
|
||||
status_.duration = time::Now() - status_.start;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
void RenderSystem::ClearImageCache()
|
||||
HRESULT Renderer::CreateLayer(ComPtr<ID2D1Layer>& layer)
|
||||
{
|
||||
bitmap_cache_.clear();
|
||||
}
|
||||
|
||||
D2DHwndRenderTargetPtr const & RenderSystem::GetRenderTarget() const
|
||||
{
|
||||
return render_target_;
|
||||
}
|
||||
|
||||
D2DSolidColorBrushPtr const & RenderSystem::GetSolidBrush() const
|
||||
{
|
||||
return solid_brush_;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::CreateLayer(D2DLayerPtr& layer)
|
||||
{
|
||||
if (!render_target_)
|
||||
if (!device_context_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
layer = nullptr;
|
||||
return render_target_->CreateLayer(&layer);
|
||||
return device_context_->CreateLayer(&layer);
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::CreateSolidColorBrush(D2DSolidColorBrushPtr & brush) const
|
||||
{
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
brush = nullptr;
|
||||
return render_target_->CreateSolidColorBrush(
|
||||
D2D1::ColorF(D2D1::ColorF::White),
|
||||
&brush
|
||||
);
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::DrawGeometry(
|
||||
D2DGeometryPtr const& geometry,
|
||||
HRESULT Renderer::DrawGeometry(
|
||||
ComPtr<ID2D1Geometry> const& geometry,
|
||||
Color const& stroke_color,
|
||||
float stroke_width,
|
||||
StrokeStyle stroke
|
||||
)
|
||||
{
|
||||
if (!solid_brush_ ||
|
||||
!render_target_)
|
||||
if (!solid_color_brush_ || !device_context_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
return S_OK;
|
||||
solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color));
|
||||
|
||||
solid_brush_->SetColor(ToD2dColorF(stroke_color));
|
||||
auto stroke_style = Factory::Instance().GetStrokeStyle(stroke);
|
||||
render_target_->DrawGeometry(
|
||||
device_context_->DrawGeometry(
|
||||
geometry.Get(),
|
||||
solid_brush_.Get(),
|
||||
solid_color_brush_.Get(),
|
||||
stroke_width,
|
||||
stroke_style.Get()
|
||||
device_resources_->GetStrokeStyle(stroke)
|
||||
);
|
||||
|
||||
if (debug_)
|
||||
// if (debug_)
|
||||
++status_.primitives;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::FillGeometry(D2DGeometryPtr const & geometry, const Color & fill_color)
|
||||
HRESULT Renderer::FillGeometry(ComPtr<ID2D1Geometry> const & geometry, Color const& fill_color)
|
||||
{
|
||||
if (!solid_brush_ ||
|
||||
!render_target_)
|
||||
if (!solid_color_brush_ || !device_context_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
return S_OK;
|
||||
|
||||
solid_brush_->SetColor(ToD2dColorF(fill_color));
|
||||
render_target_->FillGeometry(
|
||||
solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color));
|
||||
device_context_->FillGeometry(
|
||||
geometry.Get(),
|
||||
solid_brush_.Get()
|
||||
solid_color_brush_.Get()
|
||||
);
|
||||
|
||||
if (debug_)
|
||||
++status_.primitives;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::DrawImage(ImagePtr const & image, Rect const& dest_rect)
|
||||
HRESULT Renderer::DrawImage(ImagePtr const & image, Rect const& dest_rect)
|
||||
{
|
||||
if (!render_target_)
|
||||
if (!device_context_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (!image->GetBitmap())
|
||||
return S_OK;
|
||||
|
||||
if (window_occluded_)
|
||||
return S_OK;
|
||||
|
||||
render_target_->DrawBitmap(
|
||||
device_context_->DrawBitmap(
|
||||
image->GetBitmap().Get(),
|
||||
ToD2dRectF(dest_rect),
|
||||
DX::ConvertToRectF(dest_rect),
|
||||
opacity_,
|
||||
D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
|
||||
ToD2dRectF(image->GetCropRect())
|
||||
DX::ConvertToRectF(image->GetCropRect())
|
||||
);
|
||||
|
||||
if (debug_)
|
||||
// if (debug_)
|
||||
++status_.primitives;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::DrawBitmap(
|
||||
D2DBitmapPtr const& bitmap
|
||||
)
|
||||
HRESULT Renderer::DrawBitmap(ComPtr<ID2D1Bitmap> const & bitmap)
|
||||
{
|
||||
if (!render_target_)
|
||||
if (!device_context_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
if (!bitmap)
|
||||
return S_OK;
|
||||
|
||||
// Do not crop bitmap
|
||||
auto rect = D2D1::RectF(0.f, 0.f, bitmap->GetSize().width, bitmap->GetSize().height);
|
||||
render_target_->DrawBitmap(
|
||||
D2D_RECT_F rect = D2D1::RectF(0.f, 0.f, bitmap->GetSize().width, bitmap->GetSize().height);
|
||||
device_context_->DrawBitmap(
|
||||
bitmap.Get(),
|
||||
rect,
|
||||
opacity_,
|
||||
|
|
@ -241,69 +254,56 @@ namespace easy2d
|
|||
rect
|
||||
);
|
||||
|
||||
if (debug_)
|
||||
++status_.primitives;
|
||||
// if (debug_)
|
||||
++status_.primitives;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::DrawTextLayout(D2DTextLayoutPtr const& text_layout)
|
||||
HRESULT Renderer::DrawTextLayout(ComPtr<IDWriteTextLayout> const& text_layout)
|
||||
{
|
||||
if (!text_renderer_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
return S_OK;
|
||||
|
||||
if (debug_)
|
||||
// if (debug_)
|
||||
++status_.primitives;
|
||||
return text_layout->Draw(nullptr, text_renderer_.Get(), 0, 0);
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::PushClip(const Matrix & clip_matrix, const Size & clip_size)
|
||||
HRESULT Renderer::PushClip(const Matrix & clip_matrix, const Size & clip_size)
|
||||
{
|
||||
if (!render_target_)
|
||||
if (!device_context_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
return S_OK;
|
||||
|
||||
render_target_->SetTransform(clip_matrix);
|
||||
render_target_->PushAxisAlignedClip(
|
||||
device_context_->SetTransform(DX::ConvertToMatrix3x2F(clip_matrix));
|
||||
device_context_->PushAxisAlignedClip(
|
||||
D2D1::RectF(0, 0, clip_size.x, clip_size.y),
|
||||
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
|
||||
);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::PopClip()
|
||||
HRESULT Renderer::PopClip()
|
||||
{
|
||||
if (!render_target_)
|
||||
if (!device_context_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
return S_OK;
|
||||
|
||||
render_target_->PopAxisAlignedClip();
|
||||
device_context_->PopAxisAlignedClip();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::PushLayer(D2DLayerPtr const& layer, LayerProperties const& properties)
|
||||
HRESULT Renderer::PushLayer(ComPtr<ID2D1Layer> const& layer, LayerProperties const& properties)
|
||||
{
|
||||
if (!render_target_ ||
|
||||
!solid_brush_)
|
||||
if (!device_context_ || !solid_color_brush_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
return S_OK;
|
||||
|
||||
render_target_->PushLayer(
|
||||
device_context_->PushLayer(
|
||||
D2D1::LayerParameters(
|
||||
ToD2dRectF(properties.area),
|
||||
DX::ConvertToRectF(properties.area),
|
||||
nullptr,
|
||||
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
|
||||
D2D1::Matrix3x2F::Identity(),
|
||||
properties.opacity,
|
||||
solid_brush_.Get(),
|
||||
solid_color_brush_.Get(),
|
||||
D2D1_LAYER_OPTIONS_NONE
|
||||
),
|
||||
layer.Get()
|
||||
|
|
@ -311,124 +311,39 @@ namespace easy2d
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::PopLayer()
|
||||
HRESULT Renderer::PopLayer()
|
||||
{
|
||||
if (!render_target_)
|
||||
if (!device_context_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (window_occluded_)
|
||||
return S_OK;
|
||||
|
||||
render_target_->PopLayer();
|
||||
device_context_->PopLayer();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::GetSize(Size & size)
|
||||
void Renderer::SetClearColor(const Color & color)
|
||||
{
|
||||
if (!render_target_)
|
||||
clear_color_ = DX::ConvertToColorF(color);
|
||||
}
|
||||
|
||||
HRESULT Renderer::SetTransform(const Matrix & matrix)
|
||||
{
|
||||
if (!device_context_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
auto rtsize = render_target_->GetSize();
|
||||
size.x = rtsize.width;
|
||||
size.y = rtsize.height;
|
||||
device_context_->SetTransform(DX::ConvertToMatrix3x2F(matrix));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::CreateBitmapFromFile(D2DBitmapPtr& bitmap, String const& file_path)
|
||||
void Renderer::SetOpacity(float opacity)
|
||||
{
|
||||
if (render_target_ == nullptr)
|
||||
if (opacity_ != opacity)
|
||||
{
|
||||
return E_UNEXPECTED;
|
||||
opacity_ = opacity;
|
||||
solid_color_brush_->SetOpacity(opacity);
|
||||
}
|
||||
|
||||
size_t hash_code = std::hash<String>{}(file_path);
|
||||
if (bitmap_cache_.find(hash_code) != bitmap_cache_.end())
|
||||
{
|
||||
bitmap = bitmap_cache_[hash_code];
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
D2DBitmapPtr bitmap_tmp;
|
||||
HRESULT hr = Factory::Instance().CreateBitmapFromFile(
|
||||
bitmap,
|
||||
render_target_,
|
||||
file_path
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
bitmap_cache_.insert(std::make_pair(hash_code, bitmap));
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::CreateBitmapFromResource(D2DBitmapPtr& bitmap, Resource const& res)
|
||||
{
|
||||
if (render_target_ == nullptr)
|
||||
{
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
size_t hash_code = res.GetHashCode();
|
||||
if (bitmap_cache_.find(hash_code) != bitmap_cache_.end())
|
||||
{
|
||||
bitmap = bitmap_cache_[hash_code];
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT hr = Factory::Instance().CreateBitmapFromResource(
|
||||
bitmap,
|
||||
render_target_,
|
||||
res
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
bitmap_cache_.insert(std::make_pair(hash_code, bitmap));
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::CreateBitmapRenderTarget(D2DBitmapRenderTargetPtr & brt)
|
||||
{
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
brt = nullptr;
|
||||
return render_target_->CreateCompatibleRenderTarget(&brt);
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::Resize(UINT32 width, UINT32 height)
|
||||
{
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
render_target_->Resize(D2D1::SizeU(width, height));
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::SetTransform(const Matrix & matrix)
|
||||
{
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
render_target_->SetTransform(matrix);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::SetOpacity(float opacity)
|
||||
{
|
||||
if (!render_target_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
opacity_ = opacity;
|
||||
solid_brush_->SetOpacity(opacity);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::SetTextStyle(
|
||||
HRESULT Renderer::SetTextStyle(
|
||||
Color const& color,
|
||||
bool has_outline,
|
||||
Color const& outline_color,
|
||||
|
|
@ -436,40 +351,34 @@ namespace easy2d
|
|||
StrokeStyle outline_stroke
|
||||
)
|
||||
{
|
||||
if (!text_renderer_)
|
||||
if (!text_renderer_ || !device_resources_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
auto stroke_style = Factory::Instance().GetStrokeStyle(outline_stroke);
|
||||
text_renderer_->SetTextStyle(
|
||||
ToD2dColorF(color),
|
||||
DX::ConvertToColorF(color),
|
||||
has_outline,
|
||||
ToD2dColorF(outline_color),
|
||||
DX::ConvertToColorF(outline_color),
|
||||
outline_width,
|
||||
stroke_style.Get()
|
||||
device_resources_->GetStrokeStyle(outline_stroke)
|
||||
);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void RenderSystem::SetClearColor(const Color& color)
|
||||
HRESULT Renderer::SetAntialiasMode(bool enabled)
|
||||
{
|
||||
clear_color_ = ToD2dColorF(color);
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::SetAntialiasMode(bool enabled)
|
||||
{
|
||||
if (!render_target_)
|
||||
if (!device_context_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
render_target_->SetAntialiasMode(
|
||||
device_context_->SetAntialiasMode(
|
||||
enabled ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED
|
||||
);
|
||||
antialias_ = enabled;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::SetTextAntialiasMode(TextAntialias mode)
|
||||
HRESULT Renderer::SetTextAntialiasMode(TextAntialias mode)
|
||||
{
|
||||
if (!render_target_)
|
||||
if (!device_context_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
text_antialias_ = mode;
|
||||
|
|
@ -491,78 +400,8 @@ namespace easy2d
|
|||
default:
|
||||
break;
|
||||
}
|
||||
render_target_->SetTextAntialiasMode(antialias_mode);
|
||||
device_context_->SetTextAntialiasMode(antialias_mode);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
RenderSystem::Status const & RenderSystem::GetStatus() const
|
||||
{
|
||||
return status_;
|
||||
}
|
||||
|
||||
HRESULT RenderSystem::CreateResources(HWND hwnd)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
if (!render_target_)
|
||||
{
|
||||
RECT rc;
|
||||
::GetClientRect(hwnd, &rc);
|
||||
|
||||
D2D1_SIZE_U size = D2D1::SizeU(
|
||||
rc.right - rc.left,
|
||||
rc.bottom - rc.top
|
||||
);
|
||||
|
||||
hr = Factory::Instance().CreateHwndRenderTarget(
|
||||
render_target_,
|
||||
D2D1::RenderTargetProperties(
|
||||
D2D1_RENDER_TARGET_TYPE_DEFAULT,
|
||||
D2D1::PixelFormat(),
|
||||
96.f,
|
||||
96.f
|
||||
),
|
||||
D2D1::HwndRenderTargetProperties(
|
||||
hwnd,
|
||||
size,
|
||||
vsync_enabled_ ? D2D1_PRESENT_OPTIONS_NONE : D2D1_PRESENT_OPTIONS_IMMEDIATELY
|
||||
)
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
SetAntialiasMode(antialias_);
|
||||
SetTextAntialiasMode(text_antialias_);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = render_target_->CreateSolidColorBrush(
|
||||
D2D1::ColorF(D2D1::ColorF::White),
|
||||
&solid_brush_
|
||||
);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = Factory::Instance().CreateTextRenderer(
|
||||
text_renderer_,
|
||||
render_target_,
|
||||
solid_brush_
|
||||
);
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
void RenderSystem::DiscardResources()
|
||||
{
|
||||
// FIXME! 应通知 Application 类销毁所有节点的 device resources
|
||||
fps_text_format_ = nullptr;
|
||||
fps_text_layout_ = nullptr;
|
||||
text_renderer_ = nullptr;
|
||||
solid_brush_ = nullptr;
|
||||
render_target_ = nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,45 +20,80 @@
|
|||
|
||||
#pragma once
|
||||
#include "include-forwards.h"
|
||||
#include "time.h"
|
||||
#include "Font.hpp"
|
||||
#include "Resource.h"
|
||||
#include "TextRenderer.h"
|
||||
#include "TextStyle.hpp"
|
||||
#include "Singleton.hpp"
|
||||
#include "../math/Matrix.h"
|
||||
#include <unordered_map>
|
||||
#include "../DX/helper.hpp"
|
||||
#include "../DX/DeviceResources.h"
|
||||
#include "../DX/TextRenderer.h"
|
||||
#include "time.h"
|
||||
#include <d2d1.h>
|
||||
#include <d2d1_1.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API RenderSystem
|
||||
: public Singleton<RenderSystem>
|
||||
struct RenderStatus
|
||||
{
|
||||
E2D_DECLARE_SINGLETON(RenderSystem);
|
||||
TimePoint start;
|
||||
Duration duration;
|
||||
int primitives;
|
||||
};
|
||||
|
||||
struct Status
|
||||
{
|
||||
TimePoint start;
|
||||
Duration duration;
|
||||
int primitives;
|
||||
};
|
||||
|
||||
using BitmapMap = UnorderedMap<size_t, D2DBitmapPtr>;
|
||||
class E2D_API Renderer
|
||||
: public Singleton<Renderer>
|
||||
{
|
||||
E2D_DECLARE_SINGLETON(Renderer);
|
||||
|
||||
public:
|
||||
HRESULT Init(HWND hwnd, bool vsync, bool debug);
|
||||
HRESULT Init(HWND hwnd);
|
||||
|
||||
void Destroy();
|
||||
|
||||
// 开始渲染
|
||||
HRESULT BeginDraw(HWND hwnd);
|
||||
inline RenderStatus const& GetStatus() const { return status_; }
|
||||
|
||||
inline DeviceResources* GetDeviceResources() const { return device_resources_.Get(); }
|
||||
|
||||
inline ITextRenderer* GetTextRenderer() const { return text_renderer_.Get(); }
|
||||
|
||||
inline ID2D1SolidColorBrush* GetSolidColorBrush() const { return solid_color_brush_.Get(); }
|
||||
|
||||
HRESULT BeginDraw();
|
||||
|
||||
// 结束渲染
|
||||
HRESULT EndDraw();
|
||||
|
||||
// 设置清空屏幕的颜色
|
||||
HRESULT CreateLayer(
|
||||
ComPtr<ID2D1Layer>& layer
|
||||
);
|
||||
|
||||
HRESULT DrawGeometry(
|
||||
ComPtr<ID2D1Geometry> const& geometry,
|
||||
const Color& stroke_color,
|
||||
float stroke_width,
|
||||
StrokeStyle stroke = StrokeStyle::Miter
|
||||
);
|
||||
|
||||
HRESULT FillGeometry(
|
||||
ComPtr<ID2D1Geometry> const& geometry,
|
||||
Color const& fill_color
|
||||
);
|
||||
|
||||
HRESULT DrawImage(
|
||||
ImagePtr const& image,
|
||||
Rect const& dest_rect
|
||||
);
|
||||
|
||||
HRESULT DrawBitmap(
|
||||
ComPtr<ID2D1Bitmap> const& bitmap
|
||||
);
|
||||
|
||||
HRESULT DrawTextLayout(
|
||||
ComPtr<IDWriteTextLayout> const& text_layout
|
||||
);
|
||||
|
||||
// <20>零헌팁奈<ED8C81>
|
||||
void SetClearColor(
|
||||
const Color& color
|
||||
Color const& clear_color
|
||||
);
|
||||
|
||||
// ÉèÖÿ¹¾â³Ýģʽ
|
||||
|
|
@ -71,44 +106,15 @@ namespace easy2d
|
|||
TextAntialias mode
|
||||
);
|
||||
|
||||
Status const& GetStatus() const;
|
||||
|
||||
HRESULT CreateResources(
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
void DiscardResources();
|
||||
|
||||
HRESULT CreateLayer(
|
||||
D2DLayerPtr& layer
|
||||
);
|
||||
|
||||
HRESULT CreateSolidColorBrush(
|
||||
D2DSolidColorBrushPtr& brush
|
||||
) const;
|
||||
|
||||
HRESULT CreateBitmapFromFile(
|
||||
D2DBitmapPtr& bitmap,
|
||||
String const& file_path
|
||||
);
|
||||
|
||||
HRESULT CreateBitmapFromResource(
|
||||
D2DBitmapPtr& bitmap,
|
||||
Resource const& res
|
||||
);
|
||||
|
||||
HRESULT CreateBitmapRenderTarget(
|
||||
D2DBitmapRenderTargetPtr& brt
|
||||
// <20>零뺌궝拷츠똑
|
||||
void SetOpacity(
|
||||
float opacity
|
||||
);
|
||||
|
||||
HRESULT SetTransform(
|
||||
const Matrix& matrix
|
||||
);
|
||||
|
||||
HRESULT SetOpacity(
|
||||
float opacity
|
||||
);
|
||||
|
||||
HRESULT SetTextStyle(
|
||||
const Color& color,
|
||||
bool has_outline,
|
||||
|
|
@ -117,31 +123,6 @@ namespace easy2d
|
|||
StrokeStyle outline_stroke
|
||||
);
|
||||
|
||||
HRESULT DrawGeometry(
|
||||
D2DGeometryPtr const& geometry,
|
||||
const Color& stroke_color,
|
||||
float stroke_width,
|
||||
StrokeStyle stroke = StrokeStyle::Miter
|
||||
);
|
||||
|
||||
HRESULT FillGeometry(
|
||||
D2DGeometryPtr const& geometry,
|
||||
const Color& fill_color
|
||||
);
|
||||
|
||||
HRESULT DrawImage(
|
||||
ImagePtr const& image,
|
||||
Rect const& dest_rect
|
||||
);
|
||||
|
||||
HRESULT DrawBitmap(
|
||||
D2DBitmapPtr const& bitmap
|
||||
);
|
||||
|
||||
HRESULT DrawTextLayout(
|
||||
D2DTextLayoutPtr const& text_layout
|
||||
);
|
||||
|
||||
HRESULT PushClip(
|
||||
const Matrix& clip_matrix,
|
||||
const Size& clip_size
|
||||
|
|
@ -150,46 +131,35 @@ namespace easy2d
|
|||
HRESULT PopClip();
|
||||
|
||||
HRESULT PushLayer(
|
||||
D2DLayerPtr const& layer,
|
||||
ComPtr<ID2D1Layer> const& layer,
|
||||
LayerProperties const& properties
|
||||
);
|
||||
|
||||
HRESULT PopLayer();
|
||||
|
||||
HRESULT GetSize(
|
||||
Size& size
|
||||
);
|
||||
private:
|
||||
Renderer();
|
||||
|
||||
HRESULT Resize(
|
||||
UINT32 width,
|
||||
UINT32 height
|
||||
);
|
||||
~Renderer();
|
||||
|
||||
void ClearImageCache();
|
||||
HRESULT CreateDeviceResources();
|
||||
|
||||
D2DHwndRenderTargetPtr const& GetRenderTarget() const;
|
||||
HRESULT HandleDeviceLost();
|
||||
|
||||
D2DSolidColorBrushPtr const& GetSolidBrush() const;
|
||||
private:
|
||||
float opacity_;
|
||||
bool antialias_;
|
||||
unsigned long ref_count_;
|
||||
|
||||
protected:
|
||||
RenderSystem();
|
||||
TextAntialias text_antialias_;
|
||||
D2D1_COLOR_F clear_color_;
|
||||
RenderStatus status_;
|
||||
|
||||
~RenderSystem();
|
||||
|
||||
protected:
|
||||
bool debug_;
|
||||
bool window_occluded_;
|
||||
bool vsync_enabled_;
|
||||
bool antialias_;
|
||||
float opacity_;
|
||||
D2D1_COLOR_F clear_color_;
|
||||
TextAntialias text_antialias_;
|
||||
Status status_;
|
||||
D2DTextRendererPtr text_renderer_;
|
||||
D2DSolidColorBrushPtr solid_brush_;
|
||||
D2DHwndRenderTargetPtr render_target_;
|
||||
D2DTextFormatPtr fps_text_format_;
|
||||
D2DTextLayoutPtr fps_text_layout_;
|
||||
BitmapMap bitmap_cache_;
|
||||
ComPtr<DeviceResources> device_resources_;
|
||||
ComPtr<ID2D1Factory1> factory_;
|
||||
ComPtr<ID2D1DeviceContext> device_context_;
|
||||
ComPtr<ID2D1DrawingStateBlock> drawing_state_block_;
|
||||
ComPtr<ITextRenderer> text_renderer_;
|
||||
ComPtr<ID2D1SolidColorBrush> solid_color_brush_;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,12 +53,8 @@ namespace easy2d
|
|||
{
|
||||
}
|
||||
|
||||
HRESULT Window::Init(String title, int width, int height, LPCWSTR icon, bool fullscreen, WNDPROC proc, bool debug)
|
||||
HRESULT Window::Init(String title, int width, int height, LPCWSTR icon, bool fullscreen, WNDPROC proc)
|
||||
{
|
||||
E2D_NOT_USED(debug);
|
||||
|
||||
E2D_LOG(L"Creating window");
|
||||
|
||||
HINSTANCE hinst = GetModuleHandleW(nullptr);
|
||||
WNDCLASSEX wcex = { 0 };
|
||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||
|
|
@ -160,8 +156,6 @@ namespace easy2d
|
|||
|
||||
void Window::Destroy()
|
||||
{
|
||||
E2D_LOG(L"Destroying window");
|
||||
|
||||
if (is_fullscreen_)
|
||||
RestoreResolution(device_name_);
|
||||
|
||||
|
|
|
|||
|
|
@ -60,8 +60,7 @@ namespace easy2d
|
|||
int height,
|
||||
LPCWSTR icon,
|
||||
bool fullscreen,
|
||||
WNDPROC proc,
|
||||
bool debug
|
||||
WNDPROC proc
|
||||
);
|
||||
|
||||
void Destroy();
|
||||
|
|
|
|||
|
|
@ -18,57 +18,134 @@
|
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#include "Factory.h"
|
||||
#include "logs.h"
|
||||
#include "modules.h"
|
||||
#include "Transform.hpp"
|
||||
#include "DeviceResources.h"
|
||||
#include "../core/Image.h"
|
||||
#include "../core/modules.h"
|
||||
#include "../core/logs.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
Factory::Factory()
|
||||
|
||||
D2DDeviceResources::D2DDeviceResources()
|
||||
: ref_count_(0)
|
||||
, dpi_(96.f)
|
||||
{
|
||||
CreateDeviceIndependentResources();
|
||||
}
|
||||
|
||||
Factory::~Factory()
|
||||
D2DDeviceResources::~D2DDeviceResources()
|
||||
{
|
||||
DiscardResources();
|
||||
}
|
||||
|
||||
HRESULT Factory::Init(bool debug)
|
||||
STDMETHODIMP_(unsigned long) D2DDeviceResources::AddRef()
|
||||
{
|
||||
E2D_LOG(L"Creating device-independent resources");
|
||||
return InterlockedIncrement(&ref_count_);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(unsigned long) D2DDeviceResources::Release()
|
||||
{
|
||||
unsigned long newCount = InterlockedDecrement(&ref_count_);
|
||||
|
||||
if (newCount == 0)
|
||||
{
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return newCount;
|
||||
}
|
||||
|
||||
STDMETHODIMP D2DDeviceResources::QueryInterface(
|
||||
IID const& riid,
|
||||
void** object)
|
||||
{
|
||||
if (__uuidof(IUnknown) == riid)
|
||||
{
|
||||
*object = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
*object = nullptr;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
AddRef();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void D2DDeviceResources::DiscardResources()
|
||||
{
|
||||
ClearImageCache();
|
||||
|
||||
d2d_factory_.Reset();
|
||||
d2d_device_.Reset();
|
||||
d2d_device_context_.Reset();
|
||||
d2d_target_bitmap_.Reset();
|
||||
|
||||
imaging_factory_.Reset();
|
||||
dwrite_factory_.Reset();
|
||||
|
||||
d2d_miter_stroke_style_.Reset();
|
||||
d2d_bevel_stroke_style_.Reset();
|
||||
d2d_round_stroke_style_.Reset();
|
||||
}
|
||||
|
||||
HRESULT D2DDeviceResources::CreateDeviceIndependentResources()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
ComPtr<ID2D1Factory1> d2d_factory;
|
||||
ComPtr<IWICImagingFactory> imaging_factory;
|
||||
ComPtr<IDWriteFactory> dwrite_factory;
|
||||
|
||||
D2D1_FACTORY_OPTIONS options;
|
||||
options.debugLevel = debug ? D2D1_DEBUG_LEVEL_INFORMATION : D2D1_DEBUG_LEVEL_NONE;
|
||||
HRESULT hr = modules::DirectX::Get().D2D1CreateFactory(
|
||||
ZeroMemory(&options, sizeof(D2D1_FACTORY_OPTIONS));
|
||||
#ifdef E2D_DEBUG
|
||||
options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
|
||||
#endif
|
||||
|
||||
hr = modules::DirectX::Get().D2D1CreateFactory(
|
||||
D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||
__uuidof(ID2D1Factory),
|
||||
__uuidof(ID2D1Factory1),
|
||||
&options,
|
||||
reinterpret_cast<void**>(&factory_)
|
||||
reinterpret_cast<void**>(&d2d_factory)
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
d2d_factory_ = d2d_factory;
|
||||
|
||||
CoCreateInstance(
|
||||
CLSID_WICImagingFactory,
|
||||
nullptr,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
__uuidof(IWICImagingFactory),
|
||||
reinterpret_cast<void**>(&imaging_factory_)
|
||||
reinterpret_cast<void**>(&imaging_factory)
|
||||
);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
imaging_factory_ = imaging_factory;
|
||||
|
||||
modules::DirectX::Get().DWriteCreateFactory(
|
||||
DWRITE_FACTORY_TYPE_SHARED,
|
||||
__uuidof(IDWriteFactory),
|
||||
reinterpret_cast<IUnknown**>(&write_factory_)
|
||||
reinterpret_cast<IUnknown**>(&dwrite_factory)
|
||||
);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
auto stroke_style = D2D1::StrokeStyleProperties(
|
||||
dwrite_factory_ = dwrite_factory;
|
||||
|
||||
ComPtr<ID2D1StrokeStyle> d2d_miter_stroke_style;
|
||||
ComPtr<ID2D1StrokeStyle> d2d_bevel_stroke_style;
|
||||
ComPtr<ID2D1StrokeStyle> d2d_round_stroke_style;
|
||||
|
||||
D2D1_STROKE_STYLE_PROPERTIES stroke_style = D2D1::StrokeStyleProperties(
|
||||
D2D1_CAP_STYLE_FLAT,
|
||||
D2D1_CAP_STYLE_FLAT,
|
||||
D2D1_CAP_STYLE_FLAT,
|
||||
|
|
@ -78,101 +155,89 @@ namespace easy2d
|
|||
0.0f
|
||||
);
|
||||
|
||||
hr = factory_->CreateStrokeStyle(
|
||||
hr = d2d_factory_->CreateStrokeStyle(
|
||||
stroke_style,
|
||||
nullptr,
|
||||
0,
|
||||
&miter_stroke_style_
|
||||
&d2d_miter_stroke_style
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL;
|
||||
hr = factory_->CreateStrokeStyle(
|
||||
hr = d2d_factory_->CreateStrokeStyle(
|
||||
stroke_style,
|
||||
nullptr,
|
||||
0,
|
||||
&bevel_stroke_style_
|
||||
&d2d_bevel_stroke_style
|
||||
);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND;
|
||||
hr = factory_->CreateStrokeStyle(
|
||||
hr = d2d_factory_->CreateStrokeStyle(
|
||||
stroke_style,
|
||||
nullptr,
|
||||
0,
|
||||
&round_stroke_style_
|
||||
&d2d_round_stroke_style
|
||||
);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
d2d_miter_stroke_style_ = d2d_miter_stroke_style;
|
||||
d2d_bevel_stroke_style_ = d2d_bevel_stroke_style;
|
||||
d2d_round_stroke_style_ = d2d_round_stroke_style;
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
void Factory::Destroy()
|
||||
HRESULT D2DDeviceResources::SetD2DDevice(ComPtr<ID2D1Device> const& device)
|
||||
{
|
||||
E2D_LOG(L"Destroying device-independent resources");
|
||||
ComPtr<ID2D1DeviceContext> d2d_device_ctx;
|
||||
|
||||
factory_.Reset();
|
||||
imaging_factory_.Reset();
|
||||
write_factory_.Reset();
|
||||
miter_stroke_style_.Reset();
|
||||
bevel_stroke_style_.Reset();
|
||||
round_stroke_style_.Reset();
|
||||
}
|
||||
|
||||
HRESULT Factory::CreateHwndRenderTarget(D2DHwndRenderTargetPtr & hwnd_render_target, D2D1_RENDER_TARGET_PROPERTIES const & properties, D2D1_HWND_RENDER_TARGET_PROPERTIES const & hwnd_rt_properties) const
|
||||
{
|
||||
if (!factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
D2DHwndRenderTargetPtr hwnd_render_target_tmp;
|
||||
HRESULT hr = factory_->CreateHwndRenderTarget(
|
||||
properties,
|
||||
hwnd_rt_properties,
|
||||
&hwnd_render_target_tmp
|
||||
HRESULT hr = device->CreateDeviceContext(
|
||||
D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
|
||||
&d2d_device_ctx
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
hwnd_render_target = hwnd_render_target_tmp;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Factory::CreateTextRenderer(
|
||||
D2DTextRendererPtr& text_renderer,
|
||||
D2DRenderTargetPtr const& render_target,
|
||||
D2DSolidColorBrushPtr const& brush
|
||||
)
|
||||
{
|
||||
if (!factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
D2DTextRendererPtr text_renderer_tmp;
|
||||
HRESULT hr = ITextRenderer::Create(
|
||||
&text_renderer_tmp,
|
||||
factory_.Get(),
|
||||
render_target.Get(),
|
||||
brush.Get()
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
text_renderer = text_renderer_tmp;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Factory::CreateBitmapFromFile(D2DBitmapPtr & bitmap, D2DRenderTargetPtr const & rt, String const & file_path)
|
||||
{
|
||||
if (imaging_factory_ == nullptr)
|
||||
{
|
||||
return E_UNEXPECTED;
|
||||
d2d_device_ = device;
|
||||
d2d_device_context_ = d2d_device_ctx;
|
||||
d2d_device_context_->SetDpi(dpi_, dpi_);
|
||||
}
|
||||
|
||||
IntrusivePtr<IWICBitmapDecoder> decoder;
|
||||
IntrusivePtr<IWICBitmapFrameDecode> source;
|
||||
IntrusivePtr<IWICStream> stream;
|
||||
IntrusivePtr<IWICFormatConverter> converter;
|
||||
IntrusivePtr<ID2D1Bitmap> bitmap_tmp;
|
||||
return hr;
|
||||
}
|
||||
|
||||
void D2DDeviceResources::SetTargetBitmap(ComPtr<ID2D1Bitmap1> const& target)
|
||||
{
|
||||
d2d_target_bitmap_ = target;
|
||||
if (d2d_device_context_)
|
||||
d2d_device_context_->SetTarget(d2d_target_bitmap_.Get());
|
||||
}
|
||||
|
||||
HRESULT D2DDeviceResources::CreateBitmapFromFile(ComPtr<ID2D1Bitmap> & bitmap, String const & file_path)
|
||||
{
|
||||
if (!imaging_factory_ || !d2d_device_context_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
size_t hash_code = std::hash<String>{}(file_path);
|
||||
if (bitmap_cache_.find(hash_code) != bitmap_cache_.end())
|
||||
{
|
||||
bitmap = bitmap_cache_[hash_code];
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ComPtr<IWICBitmapDecoder> decoder;
|
||||
ComPtr<IWICBitmapFrameDecode> source;
|
||||
ComPtr<IWICStream> stream;
|
||||
ComPtr<IWICFormatConverter> converter;
|
||||
ComPtr<ID2D1Bitmap> bitmap_tmp;
|
||||
|
||||
HRESULT hr = imaging_factory_->CreateDecoderFromFilename(
|
||||
file_path.c_str(),
|
||||
|
|
@ -207,7 +272,7 @@ namespace easy2d
|
|||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = rt->CreateBitmapFromWicBitmap(
|
||||
hr = d2d_device_context_->CreateBitmapFromWicBitmap(
|
||||
converter.Get(),
|
||||
nullptr,
|
||||
&bitmap_tmp
|
||||
|
|
@ -215,24 +280,32 @@ namespace easy2d
|
|||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
bitmap = bitmap_tmp;
|
||||
bitmap_cache_.insert(std::make_pair(hash_code, bitmap));
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Factory::CreateBitmapFromResource(D2DBitmapPtr & bitmap, D2DRenderTargetPtr const & rt, Resource const & res)
|
||||
HRESULT D2DDeviceResources::CreateBitmapFromResource(ComPtr<ID2D1Bitmap> & bitmap, Resource const & res)
|
||||
{
|
||||
if (imaging_factory_ == nullptr)
|
||||
{
|
||||
if (!imaging_factory_ || !d2d_device_context_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
size_t hash_code = res.GetHashCode();
|
||||
if (bitmap_cache_.find(hash_code) != bitmap_cache_.end())
|
||||
{
|
||||
bitmap = bitmap_cache_[hash_code];
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IntrusivePtr<IWICBitmapDecoder> decoder;
|
||||
IntrusivePtr<IWICBitmapFrameDecode> source;
|
||||
IntrusivePtr<IWICStream> stream;
|
||||
IntrusivePtr<IWICFormatConverter> converter;
|
||||
IntrusivePtr<ID2D1Bitmap> bitmap_tmp;
|
||||
|
||||
ComPtr<IWICBitmapDecoder> decoder;
|
||||
ComPtr<IWICBitmapFrameDecode> source;
|
||||
ComPtr<IWICStream> stream;
|
||||
ComPtr<IWICFormatConverter> converter;
|
||||
ComPtr<ID2D1Bitmap> bitmap_tmp;
|
||||
|
||||
// ¼ÓÔØ×ÊÔ´
|
||||
LPVOID buffer;
|
||||
DWORD buffer_size;
|
||||
|
|
@ -286,7 +359,7 @@ namespace easy2d
|
|||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = rt->CreateBitmapFromWicBitmap(
|
||||
hr = d2d_device_context_->CreateBitmapFromWicBitmap(
|
||||
converter.Get(),
|
||||
nullptr,
|
||||
&bitmap_tmp
|
||||
|
|
@ -296,105 +369,19 @@ namespace easy2d
|
|||
if (SUCCEEDED(hr))
|
||||
{
|
||||
bitmap = bitmap_tmp;
|
||||
bitmap_cache_.insert(std::make_pair(hash_code, bitmap));
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Factory::CreateRectangleGeometry(D2DRectangleGeometryPtr & geo, Rect const& rect) const
|
||||
HRESULT D2DDeviceResources::CreateTextFormat(ComPtr<IDWriteTextFormat> & text_format, Font const & font, TextStyle const & text_style) const
|
||||
{
|
||||
if (!factory_)
|
||||
if (!dwrite_factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
D2DRectangleGeometryPtr rectangle;
|
||||
HRESULT hr = factory_->CreateRectangleGeometry(
|
||||
ToD2dRectF(rect),
|
||||
&rectangle
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
geo = rectangle;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Factory::CreateRoundedRectangleGeometry(D2DRoundedRectangleGeometryPtr & geo, Rect const & rect, float radius_x, float radius_y) const
|
||||
{
|
||||
if (!factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
D2DRoundedRectangleGeometryPtr rounded_rect;
|
||||
HRESULT hr = factory_->CreateRoundedRectangleGeometry(
|
||||
D2D1::RoundedRect(
|
||||
ToD2dRectF(rect),
|
||||
radius_x,
|
||||
radius_y
|
||||
),
|
||||
&rounded_rect
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
geo = rounded_rect;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Factory::CreateEllipseGeometry(D2DEllipseGeometryPtr & geo, Point const & center, float radius_x, float radius_y) const
|
||||
{
|
||||
if (!factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
D2DEllipseGeometryPtr ellipse;
|
||||
HRESULT hr = factory_->CreateEllipseGeometry(
|
||||
D2D1::Ellipse(
|
||||
ToD2dPoint2F(center),
|
||||
radius_x,
|
||||
radius_y
|
||||
),
|
||||
&ellipse
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
geo = ellipse;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Factory::CreateTransformedGeometry(
|
||||
D2DTransformedGeometryPtr& transformed,
|
||||
Matrix const& matrix,
|
||||
D2DGeometryPtr const& geo
|
||||
) const
|
||||
{
|
||||
if (!factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
D2DTransformedGeometryPtr transformed_tmp;
|
||||
HRESULT hr = factory_->CreateTransformedGeometry(
|
||||
geo.Get(),
|
||||
matrix,
|
||||
&transformed_tmp
|
||||
);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
transformed = transformed_tmp;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Factory::CreatePathGeometry(D2DPathGeometryPtr & geometry) const
|
||||
{
|
||||
if (!factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
return factory_->CreatePathGeometry(&geometry);
|
||||
}
|
||||
|
||||
HRESULT Factory::CreateTextFormat(D2DTextFormatPtr & text_format, Font const & font, TextStyle const & text_style) const
|
||||
{
|
||||
if (!write_factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
D2DTextFormatPtr text_format_tmp;
|
||||
HRESULT hr = write_factory_->CreateTextFormat(
|
||||
ComPtr<IDWriteTextFormat> text_format_tmp;
|
||||
HRESULT hr = dwrite_factory_->CreateTextFormat(
|
||||
font.family.c_str(),
|
||||
nullptr,
|
||||
DWRITE_FONT_WEIGHT(font.weight),
|
||||
|
|
@ -426,20 +413,20 @@ namespace easy2d
|
|||
return hr;
|
||||
}
|
||||
|
||||
HRESULT Factory::CreateTextLayout(D2DTextLayoutPtr & text_layout, Size& layout_size, String const & text, D2DTextFormatPtr const& text_format, TextStyle const & text_style) const
|
||||
HRESULT D2DDeviceResources::CreateTextLayout(ComPtr<IDWriteTextLayout> & text_layout, Size& layout_size, String const & text, ComPtr<IDWriteTextFormat> const& text_format, TextStyle const & text_style) const
|
||||
{
|
||||
if (!write_factory_)
|
||||
if (!dwrite_factory_)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
text_layout = nullptr;
|
||||
|
||||
HRESULT hr;
|
||||
D2DTextLayoutPtr text_layout_tmp;
|
||||
ComPtr<IDWriteTextLayout> text_layout_tmp;
|
||||
UINT32 length = static_cast<UINT32>(text.length());
|
||||
|
||||
if (text_style.wrap)
|
||||
{
|
||||
hr = write_factory_->CreateTextLayout(
|
||||
hr = dwrite_factory_->CreateTextLayout(
|
||||
text.c_str(),
|
||||
length,
|
||||
text_format.Get(),
|
||||
|
|
@ -450,7 +437,7 @@ namespace easy2d
|
|||
}
|
||||
else
|
||||
{
|
||||
hr = write_factory_->CreateTextLayout(
|
||||
hr = dwrite_factory_->CreateTextLayout(
|
||||
text.c_str(),
|
||||
length,
|
||||
text_format.Get(),
|
||||
|
|
@ -468,7 +455,7 @@ namespace easy2d
|
|||
if (SUCCEEDED(hr))
|
||||
{
|
||||
text_layout_tmp = nullptr;
|
||||
hr = write_factory_->CreateTextLayout(
|
||||
hr = dwrite_factory_->CreateTextLayout(
|
||||
text.c_str(),
|
||||
length,
|
||||
text_format.Get(),
|
||||
|
|
@ -507,21 +494,20 @@ namespace easy2d
|
|||
return hr;
|
||||
}
|
||||
|
||||
D2DStrokeStylePtr const& Factory::GetStrokeStyle(StrokeStyle stroke) const
|
||||
void D2DDeviceResources::ClearImageCache()
|
||||
{
|
||||
bitmap_cache_.clear();
|
||||
}
|
||||
|
||||
ID2D1StrokeStyle* D2DDeviceResources::GetStrokeStyle(StrokeStyle stroke) const
|
||||
{
|
||||
switch (stroke)
|
||||
{
|
||||
case StrokeStyle::Miter:
|
||||
return miter_stroke_style_;
|
||||
break;
|
||||
case StrokeStyle::Bevel:
|
||||
return bevel_stroke_style_;
|
||||
break;
|
||||
case StrokeStyle::Round:
|
||||
return round_stroke_style_;
|
||||
break;
|
||||
case StrokeStyle::Miter: return d2d_miter_stroke_style_.Get(); break;
|
||||
case StrokeStyle::Bevel: return d2d_bevel_stroke_style_.Get(); break;
|
||||
case StrokeStyle::Round: return d2d_round_stroke_style_.Get(); break;
|
||||
}
|
||||
return miter_stroke_style_;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - 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 "helper.hpp"
|
||||
#include "../core/Resource.h"
|
||||
#include "../core/Font.hpp"
|
||||
#include "../core/TextStyle.hpp"
|
||||
#include <d2d1.h>
|
||||
#include <d2d1_1.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API D2DDeviceResources
|
||||
: public IUnknown
|
||||
{
|
||||
public:
|
||||
HRESULT CreateBitmapFromFile(
|
||||
_Out_ ComPtr<ID2D1Bitmap>& bitmap,
|
||||
_In_ String const& file_path
|
||||
);
|
||||
|
||||
HRESULT CreateBitmapFromResource(
|
||||
_Out_ ComPtr<ID2D1Bitmap>& bitmap,
|
||||
_In_ Resource const& res
|
||||
);
|
||||
|
||||
HRESULT CreateTextFormat(
|
||||
_Out_ ComPtr<IDWriteTextFormat>& text_format,
|
||||
_In_ Font const& font,
|
||||
_In_ TextStyle const& text_style
|
||||
) const;
|
||||
|
||||
HRESULT CreateTextLayout(
|
||||
_Out_ ComPtr<IDWriteTextLayout>& text_layout,
|
||||
_Out_ Size& layout_size,
|
||||
_In_ String const& text,
|
||||
_In_ ComPtr<IDWriteTextFormat> const& text_format,
|
||||
_In_ TextStyle const& text_style
|
||||
) const;
|
||||
|
||||
void ClearImageCache();
|
||||
|
||||
void DiscardResources();
|
||||
|
||||
HRESULT SetD2DDevice(
|
||||
_In_ ComPtr<ID2D1Device> const& device
|
||||
);
|
||||
|
||||
void SetTargetBitmap(
|
||||
_In_ ComPtr<ID2D1Bitmap1> const& target
|
||||
);
|
||||
|
||||
inline ID2D1Factory1* GetD2DFactory() const { return d2d_factory_.Get(); }
|
||||
inline IWICImagingFactory* GetWICImagingFactory() const { return imaging_factory_.Get(); }
|
||||
inline IDWriteFactory* GetDWriteFactory() const { return dwrite_factory_.Get(); }
|
||||
inline ID2D1Device* GetD2DDevice() const { return d2d_device_.Get(); }
|
||||
inline ID2D1DeviceContext* GetD2DDeviceContext() const { return d2d_device_context_.Get(); }
|
||||
inline ID2D1Bitmap1* GetD2DTargetBitmap() const { return d2d_target_bitmap_.Get(); }
|
||||
|
||||
ID2D1StrokeStyle* GetStrokeStyle(StrokeStyle stroke) const;
|
||||
|
||||
public:
|
||||
unsigned long STDMETHODCALLTYPE AddRef();
|
||||
|
||||
unsigned long STDMETHODCALLTYPE Release();
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(
|
||||
IID const& riid,
|
||||
void** ppvObject
|
||||
);
|
||||
|
||||
protected:
|
||||
D2DDeviceResources();
|
||||
|
||||
virtual ~D2DDeviceResources();
|
||||
|
||||
HRESULT CreateDeviceIndependentResources();
|
||||
|
||||
private:
|
||||
unsigned long ref_count_;
|
||||
float dpi_;
|
||||
|
||||
using BitmapMap = UnorderedMap<size_t, ComPtr<ID2D1Bitmap>>;
|
||||
BitmapMap bitmap_cache_;
|
||||
|
||||
ComPtr<ID2D1Factory1> d2d_factory_;
|
||||
ComPtr<ID2D1Device> d2d_device_;
|
||||
ComPtr<ID2D1DeviceContext> d2d_device_context_;
|
||||
ComPtr<ID2D1Bitmap1> d2d_target_bitmap_;
|
||||
|
||||
ComPtr<IWICImagingFactory> imaging_factory_;
|
||||
ComPtr<IDWriteFactory> dwrite_factory_;
|
||||
|
||||
ComPtr<ID2D1StrokeStyle> d2d_miter_stroke_style_;
|
||||
ComPtr<ID2D1StrokeStyle> d2d_bevel_stroke_style_;
|
||||
ComPtr<ID2D1StrokeStyle> d2d_round_stroke_style_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,387 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - 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.
|
||||
|
||||
#include "DeviceResources.h"
|
||||
#include "../core/Image.h"
|
||||
#include "../core/modules.h"
|
||||
#include "../core/logs.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
#if defined(_DEBUG)
|
||||
namespace DX
|
||||
{
|
||||
inline bool SdkLayersAvailable()
|
||||
{
|
||||
HRESULT hr = modules::DirectX::Get().D3D11CreateDevice(
|
||||
nullptr,
|
||||
D3D_DRIVER_TYPE_NULL, // There is no need to create a real hardware device.
|
||||
0,
|
||||
D3D11_CREATE_DEVICE_DEBUG, // Check for the SDK layers.
|
||||
nullptr, // Any feature level will do.
|
||||
0,
|
||||
D3D11_SDK_VERSION, // Always set this to D3D11_SDK_VERSION for Windows Runtime apps.
|
||||
nullptr, // No need to keep the D3D device reference.
|
||||
nullptr, // No need to know the feature level.
|
||||
nullptr // No need to keep the D3D device context reference.
|
||||
);
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
D3D11DeviceResources::D3D11DeviceResources()
|
||||
: hwnd_(nullptr)
|
||||
, d3d_feature_level_(D3D_FEATURE_LEVEL_9_1)
|
||||
{
|
||||
dpi_ = 96.f; // dpi_ = (float)GetDpiForWindow(hwnd);
|
||||
}
|
||||
|
||||
D3D11DeviceResources::~D3D11DeviceResources()
|
||||
{
|
||||
DiscardResources();
|
||||
}
|
||||
|
||||
HRESULT D3D11DeviceResources::Create(D3D11DeviceResources** device_resources, HWND hwnd)
|
||||
{
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
if (device_resources)
|
||||
{
|
||||
D3D11DeviceResources* res = new (std::nothrow) D3D11DeviceResources;
|
||||
if (res)
|
||||
{
|
||||
hr = res->CreateDeviceIndependentResources();
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
RECT rc;
|
||||
GetClientRect(hwnd, &rc);
|
||||
|
||||
res->hwnd_ = hwnd;
|
||||
res->logical_size_.x = float(rc.right - rc.left);
|
||||
res->logical_size_.y = float(rc.bottom - rc.top);
|
||||
|
||||
hr = res->CreateDeviceResources();
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = res->CreateWindowSizeDependentResources();
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
res->AddRef();
|
||||
|
||||
DX::SafeRelease(*device_resources);
|
||||
(*device_resources) = res;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete res;
|
||||
res = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
void D3D11DeviceResources::DiscardResources()
|
||||
{
|
||||
d3d_device_.Reset();
|
||||
d3d_device_context_.Reset();
|
||||
dxgi_swap_chain_.Reset();
|
||||
dxgi_factory_.Reset();
|
||||
|
||||
hwnd_ = nullptr;
|
||||
}
|
||||
|
||||
HRESULT D3D11DeviceResources::CreateDeviceResources()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
D3D_FEATURE_LEVEL feature_levels[] =
|
||||
{
|
||||
D3D_FEATURE_LEVEL_11_1,
|
||||
D3D_FEATURE_LEVEL_11_0,
|
||||
D3D_FEATURE_LEVEL_10_1,
|
||||
D3D_FEATURE_LEVEL_10_0,
|
||||
D3D_FEATURE_LEVEL_9_3,
|
||||
D3D_FEATURE_LEVEL_9_2,
|
||||
D3D_FEATURE_LEVEL_9_1
|
||||
};
|
||||
|
||||
ComPtr<ID3D11Device> device;
|
||||
ComPtr<ID3D11DeviceContext> context;
|
||||
|
||||
// This flag adds support for surfaces with a different color channel ordering
|
||||
// than the API default. It is required for compatibility with Direct2D.
|
||||
UINT creation_flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
|
||||
|
||||
#if defined(E2D_DEBUG)
|
||||
if (DX::SdkLayersAvailable())
|
||||
{
|
||||
creation_flags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
}
|
||||
#endif
|
||||
|
||||
hr = modules::DirectX::Get().D3D11CreateDevice(
|
||||
nullptr, // Specify nullptr to use the default adapter.
|
||||
D3D_DRIVER_TYPE_HARDWARE,
|
||||
0, // Should be 0 unless the driver is D3D_DRIVER_TYPE_SOFTWARE.
|
||||
creation_flags, // Set debug and Direct2D compatibility flags.
|
||||
feature_levels, // List of feature levels this app can support.
|
||||
ARRAYSIZE(feature_levels), // Size of the list above.
|
||||
D3D11_SDK_VERSION,
|
||||
&device, // Returns the Direct3D device created.
|
||||
&d3d_feature_level_, // Returns feature level of device created.
|
||||
&context // Returns the device immediate context.
|
||||
);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
// If the initialization fails, fall back to the WARP device.
|
||||
// For more information on WARP, see:
|
||||
// http://go.microsoft.com/fwlink/?LinkId=286690
|
||||
hr = modules::DirectX::Get().D3D11CreateDevice(
|
||||
nullptr,
|
||||
D3D_DRIVER_TYPE_WARP, // Create a WARP device instead of a hardware device.
|
||||
0,
|
||||
creation_flags,
|
||||
feature_levels,
|
||||
ARRAYSIZE(feature_levels),
|
||||
D3D11_SDK_VERSION,
|
||||
&device,
|
||||
&d3d_feature_level_,
|
||||
&context
|
||||
);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
d3d_device_ = device;
|
||||
d3d_device_context_ = context;
|
||||
|
||||
ComPtr<IDXGIAdapter> dxgi_adapter;
|
||||
ComPtr<IDXGIDevice> dxgi_device;
|
||||
ComPtr<IDXGIFactory> dxgi_factory;
|
||||
ComPtr<ID2D1Device> d2d_device;
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = d3d_device_->QueryInterface(IID_PPV_ARGS(&dxgi_device));
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = dxgi_device->GetAdapter(&dxgi_adapter);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = dxgi_adapter->GetParent(IID_PPV_ARGS(&dxgi_factory));
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
dxgi_factory_ = dxgi_factory;
|
||||
}
|
||||
|
||||
// Create the Direct2D device object and a corresponding context.
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = GetD2DFactory()->CreateDevice(dxgi_device.Get(), &d2d_device);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = SetD2DDevice(d2d_device);
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT D3D11DeviceResources::CreateWindowSizeDependentResources()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// Clear the previous window size specific context.
|
||||
ID3D11RenderTargetView* null_views[] = { nullptr };
|
||||
SetTargetBitmap(nullptr);
|
||||
d3d_device_context_->OMSetRenderTargets(ARRAYSIZE(null_views), null_views, nullptr);
|
||||
d3d_device_context_->Flush();
|
||||
|
||||
// Calculate the necessary render target size in pixels.
|
||||
output_size_.x = DX::ConvertDipsToPixels(logical_size_.x, dpi_);
|
||||
output_size_.y = DX::ConvertDipsToPixels(logical_size_.y, dpi_);
|
||||
|
||||
// Prevent zero size DirectX content from being created.
|
||||
output_size_.x = std::max(output_size_.x, 1.f);
|
||||
output_size_.y = std::max(output_size_.y, 1.f);
|
||||
|
||||
if (dxgi_swap_chain_)
|
||||
{
|
||||
// If the swap chain already exists, resize it.
|
||||
hr = dxgi_swap_chain_->ResizeBuffers(
|
||||
2, // Double-buffered swap chain.
|
||||
::lround(output_size_.x),
|
||||
::lround(output_size_.y),
|
||||
DXGI_FORMAT_B8G8R8A8_UNORM,
|
||||
0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Setup swap chain
|
||||
DXGI_SWAP_CHAIN_DESC swap_chain_desc = { 0 };
|
||||
|
||||
swap_chain_desc.BufferCount = 2;
|
||||
swap_chain_desc.BufferDesc.Width = ::lround(output_size_.x);
|
||||
swap_chain_desc.BufferDesc.Height = ::lround(output_size_.y);
|
||||
swap_chain_desc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||
swap_chain_desc.BufferDesc.RefreshRate.Numerator = 60;
|
||||
swap_chain_desc.BufferDesc.RefreshRate.Denominator = 1;
|
||||
swap_chain_desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
swap_chain_desc.OutputWindow = hwnd_;
|
||||
swap_chain_desc.SampleDesc.Count = 1;
|
||||
swap_chain_desc.SampleDesc.Quality = 0;
|
||||
swap_chain_desc.Windowed = TRUE;
|
||||
swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
|
||||
ComPtr<IDXGIDevice> dxgi_device;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = d3d_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(
|
||||
d3d_device_.Get(),
|
||||
&swap_chain_desc,
|
||||
&dxgi_swap_chain_);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// Set the 3D rendering viewport to target the entire window.
|
||||
CD3D11_VIEWPORT screen_viewport(
|
||||
0.0f,
|
||||
0.0f,
|
||||
output_size_.x,
|
||||
output_size_.y);
|
||||
|
||||
d3d_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))
|
||||
{
|
||||
D2D1_BITMAP_PROPERTIES1 bitmap_props =
|
||||
D2D1::BitmapProperties1(
|
||||
D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
|
||||
D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
|
||||
dpi_,
|
||||
dpi_);
|
||||
|
||||
ComPtr<IDXGISurface> dxgi_back_buffer;
|
||||
hr = dxgi_swap_chain_->GetBuffer(0, IID_PPV_ARGS(&dxgi_back_buffer));
|
||||
|
||||
ComPtr<ID2D1Bitmap1> target;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = GetD2DDeviceContext()->CreateBitmapFromDxgiSurface(
|
||||
dxgi_back_buffer.Get(),
|
||||
&bitmap_props,
|
||||
&target);
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
SetTargetBitmap(target);
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT D3D11DeviceResources::HandleDeviceLost()
|
||||
{
|
||||
dxgi_swap_chain_ = nullptr;
|
||||
|
||||
HRESULT hr = CreateDeviceResources();
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = CreateWindowSizeDependentResources();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
void D3D11DeviceResources::SetLogicalSize(Size logical_size)
|
||||
{
|
||||
if (logical_size_ != logical_size)
|
||||
{
|
||||
logical_size_ = logical_size;
|
||||
|
||||
ThrowIfFailed(
|
||||
CreateWindowSizeDependentResources()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void D3D11DeviceResources::SetDpi(float dpi)
|
||||
{
|
||||
if (dpi != dpi_)
|
||||
{
|
||||
dpi_ = dpi;
|
||||
|
||||
RECT rc;
|
||||
GetClientRect(hwnd_, &rc);
|
||||
|
||||
logical_size_.x = float(rc.right - rc.left);
|
||||
logical_size_.y = float(rc.bottom - rc.top);
|
||||
|
||||
GetD2DDeviceContext()->SetDpi(dpi_, dpi_);
|
||||
|
||||
ThrowIfFailed(
|
||||
CreateWindowSizeDependentResources()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - 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 "helper.hpp"
|
||||
#include "D2DDeviceResources.h"
|
||||
#include <d3d11.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
class E2D_API D3D11DeviceResources
|
||||
: public D2DDeviceResources
|
||||
{
|
||||
public:
|
||||
static HRESULT Create(
|
||||
D3D11DeviceResources** device_resources,
|
||||
HWND hwnd
|
||||
);
|
||||
|
||||
HRESULT HandleDeviceLost();
|
||||
|
||||
void SetLogicalSize(
|
||||
Size logical_size
|
||||
);
|
||||
|
||||
void SetDpi(
|
||||
float dpi
|
||||
);
|
||||
|
||||
void DiscardResources();
|
||||
|
||||
inline ID3D11Device* GetD3DDevice() const { return d3d_device_.Get(); }
|
||||
inline ID3D11DeviceContext* GetD3DDeviceContext() const { return d3d_device_context_.Get(); }
|
||||
inline IDXGIFactory* GetDXGIFactory() const { return dxgi_factory_.Get(); }
|
||||
inline IDXGISwapChain* GetDXGISwapChain() const { return dxgi_swap_chain_.Get(); }
|
||||
|
||||
inline D3D_FEATURE_LEVEL GetDeviceFeatureLevel() const { return d3d_feature_level_; }
|
||||
inline Size const& GetLogicalSize() const { return logical_size_; }
|
||||
inline Size const& GetOutputSize() const { return output_size_; }
|
||||
inline float GetDpi() const { return dpi_; }
|
||||
|
||||
protected:
|
||||
D3D11DeviceResources();
|
||||
|
||||
virtual ~D3D11DeviceResources();
|
||||
|
||||
protected:
|
||||
HRESULT CreateDeviceResources();
|
||||
|
||||
HRESULT CreateWindowSizeDependentResources();
|
||||
|
||||
private:
|
||||
HWND hwnd_;
|
||||
float dpi_;
|
||||
Size logical_size_;
|
||||
Size output_size_;
|
||||
D3D_FEATURE_LEVEL d3d_feature_level_;
|
||||
|
||||
ComPtr<ID3D11Device> d3d_device_;
|
||||
ComPtr<ID3D11DeviceContext> d3d_device_context_;
|
||||
ComPtr<IDXGISwapChain> dxgi_swap_chain_;
|
||||
ComPtr<IDXGIFactory> dxgi_factory_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - 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 "D3D11DeviceResources.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
using DeviceResources = D3D11DeviceResources;
|
||||
}
|
||||
|
|
@ -24,17 +24,17 @@
|
|||
|
||||
namespace easy2d
|
||||
{
|
||||
class TextRendererImpl
|
||||
class TextRenderer
|
||||
: public ITextRenderer
|
||||
{
|
||||
public:
|
||||
TextRendererImpl(
|
||||
ID2D1Factory* pD2DFactory,
|
||||
ID2D1RenderTarget* pRT,
|
||||
ID2D1SolidColorBrush* pBrush
|
||||
TextRenderer(
|
||||
ID2D1RenderTarget* pRT
|
||||
);
|
||||
|
||||
~TextRendererImpl();
|
||||
~TextRenderer();
|
||||
|
||||
STDMETHOD(CreateDeviceResources)();
|
||||
|
||||
STDMETHOD_(void, SetTextStyle)(
|
||||
CONST D2D1_COLOR_F &fillColor,
|
||||
|
|
@ -109,7 +109,7 @@ namespace easy2d
|
|||
D2D1_COLOR_F sOutlineColor_;
|
||||
FLOAT fOutlineWidth;
|
||||
BOOL bShowOutline_;
|
||||
ID2D1Factory* pD2DFactory_;
|
||||
ID2D1Factory* pFactory_;
|
||||
ID2D1RenderTarget* pRT_;
|
||||
ID2D1SolidColorBrush* pBrush_;
|
||||
ID2D1StrokeStyle* pCurrStrokeStyle_;
|
||||
|
|
@ -117,43 +117,72 @@ namespace easy2d
|
|||
|
||||
HRESULT ITextRenderer::Create(
|
||||
ITextRenderer** ppTextRenderer,
|
||||
ID2D1Factory* pD2DFactory,
|
||||
ID2D1RenderTarget* pRT,
|
||||
ID2D1SolidColorBrush* pBrush)
|
||||
ID2D1RenderTarget* pRT)
|
||||
{
|
||||
*ppTextRenderer = new (std::nothrow) TextRendererImpl(pD2DFactory, pRT, pBrush);
|
||||
if (*ppTextRenderer)
|
||||
HRESULT hr = E_FAIL;
|
||||
|
||||
if (ppTextRenderer)
|
||||
{
|
||||
(*ppTextRenderer)->AddRef();
|
||||
return S_OK;
|
||||
TextRenderer* pTextRenderer = new (std::nothrow) TextRenderer(pRT);
|
||||
if (pTextRenderer)
|
||||
{
|
||||
hr = pTextRenderer->CreateDeviceResources();
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
pTextRenderer->AddRef();
|
||||
|
||||
DX::SafeRelease(*ppTextRenderer);
|
||||
(*ppTextRenderer) = pTextRenderer;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pTextRenderer;
|
||||
pTextRenderer = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return E_FAIL;
|
||||
return hr;
|
||||
}
|
||||
|
||||
TextRendererImpl::TextRendererImpl(ID2D1Factory* pD2DFactory, ID2D1RenderTarget* pRT, ID2D1SolidColorBrush* pBrush)
|
||||
TextRenderer::TextRenderer(ID2D1RenderTarget* pRT)
|
||||
: cRefCount_(0)
|
||||
, pD2DFactory_(pD2DFactory)
|
||||
, pFactory_(NULL)
|
||||
, pRT_(pRT)
|
||||
, pBrush_(pBrush)
|
||||
, pBrush_(NULL)
|
||||
, sFillColor_()
|
||||
, sOutlineColor_()
|
||||
, fOutlineWidth(1)
|
||||
, bShowOutline_(TRUE)
|
||||
, pCurrStrokeStyle_(nullptr)
|
||||
, pCurrStrokeStyle_(NULL)
|
||||
{
|
||||
pD2DFactory->AddRef();
|
||||
pRT->AddRef();
|
||||
pBrush->AddRef();
|
||||
pRT_->AddRef();
|
||||
pRT_->GetFactory(&pFactory_);
|
||||
}
|
||||
|
||||
TextRendererImpl::~TextRendererImpl()
|
||||
TextRenderer::~TextRenderer()
|
||||
{
|
||||
SafeRelease(pD2DFactory_);
|
||||
SafeRelease(pRT_);
|
||||
SafeRelease(pBrush_);
|
||||
DX::SafeRelease(pFactory_);
|
||||
DX::SafeRelease(pRT_);
|
||||
DX::SafeRelease(pBrush_);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) TextRendererImpl::SetTextStyle(
|
||||
STDMETHODIMP TextRenderer::CreateDeviceResources()
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
DX::SafeRelease(pBrush_);
|
||||
|
||||
hr = pRT_->CreateSolidColorBrush(
|
||||
D2D1::ColorF(D2D1::ColorF::White),
|
||||
&pBrush_
|
||||
);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) TextRenderer::SetTextStyle(
|
||||
CONST D2D1_COLOR_F &fillColor,
|
||||
BOOL outline,
|
||||
CONST D2D1_COLOR_F &outlineColor,
|
||||
|
|
@ -167,7 +196,7 @@ namespace easy2d
|
|||
pCurrStrokeStyle_ = outlineJoin;
|
||||
}
|
||||
|
||||
STDMETHODIMP TextRendererImpl::DrawGlyphRun(
|
||||
STDMETHODIMP TextRenderer::DrawGlyphRun(
|
||||
__maybenull void* clientDrawingContext,
|
||||
FLOAT baselineOriginX,
|
||||
FLOAT baselineOriginY,
|
||||
|
|
@ -183,12 +212,12 @@ namespace easy2d
|
|||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
ID2D1PathGeometry* pPathGeometry = nullptr;
|
||||
hr = pD2DFactory_->CreatePathGeometry(
|
||||
ID2D1PathGeometry* pPathGeometry = NULL;
|
||||
hr = pFactory_->CreatePathGeometry(
|
||||
&pPathGeometry
|
||||
);
|
||||
|
||||
ID2D1GeometrySink* pSink = nullptr;
|
||||
ID2D1GeometrySink* pSink = NULL;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = pPathGeometry->Open(
|
||||
|
|
@ -221,10 +250,10 @@ namespace easy2d
|
|||
baselineOriginX, baselineOriginY
|
||||
);
|
||||
|
||||
ID2D1TransformedGeometry* pTransformedGeometry = nullptr;
|
||||
ID2D1TransformedGeometry* pTransformedGeometry = NULL;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = pD2DFactory_->CreateTransformedGeometry(
|
||||
hr = pFactory_->CreateTransformedGeometry(
|
||||
pPathGeometry,
|
||||
&matrix,
|
||||
&pTransformedGeometry
|
||||
|
|
@ -253,14 +282,14 @@ namespace easy2d
|
|||
);
|
||||
}
|
||||
|
||||
SafeRelease(pPathGeometry);
|
||||
SafeRelease(pSink);
|
||||
SafeRelease(pTransformedGeometry);
|
||||
DX::SafeRelease(pPathGeometry);
|
||||
DX::SafeRelease(pSink);
|
||||
DX::SafeRelease(pTransformedGeometry);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP TextRendererImpl::DrawUnderline(
|
||||
STDMETHODIMP TextRenderer::DrawUnderline(
|
||||
__maybenull void* clientDrawingContext,
|
||||
FLOAT baselineOriginX,
|
||||
FLOAT baselineOriginY,
|
||||
|
|
@ -279,8 +308,8 @@ namespace easy2d
|
|||
underline->offset + underline->thickness
|
||||
);
|
||||
|
||||
ID2D1RectangleGeometry* pRectangleGeometry = nullptr;
|
||||
hr = pD2DFactory_->CreateRectangleGeometry(
|
||||
ID2D1RectangleGeometry* pRectangleGeometry = NULL;
|
||||
hr = pFactory_->CreateRectangleGeometry(
|
||||
&rect,
|
||||
&pRectangleGeometry
|
||||
);
|
||||
|
|
@ -291,10 +320,10 @@ namespace easy2d
|
|||
baselineOriginX, baselineOriginY
|
||||
);
|
||||
|
||||
ID2D1TransformedGeometry* pTransformedGeometry = nullptr;
|
||||
ID2D1TransformedGeometry* pTransformedGeometry = NULL;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = pD2DFactory_->CreateTransformedGeometry(
|
||||
hr = pFactory_->CreateTransformedGeometry(
|
||||
pRectangleGeometry,
|
||||
&matrix,
|
||||
&pTransformedGeometry
|
||||
|
|
@ -323,13 +352,13 @@ namespace easy2d
|
|||
);
|
||||
}
|
||||
|
||||
SafeRelease(pRectangleGeometry);
|
||||
SafeRelease(pTransformedGeometry);
|
||||
DX::SafeRelease(pRectangleGeometry);
|
||||
DX::SafeRelease(pTransformedGeometry);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP TextRendererImpl::DrawStrikethrough(
|
||||
STDMETHODIMP TextRenderer::DrawStrikethrough(
|
||||
__maybenull void* clientDrawingContext,
|
||||
FLOAT baselineOriginX,
|
||||
FLOAT baselineOriginY,
|
||||
|
|
@ -348,8 +377,8 @@ namespace easy2d
|
|||
strikethrough->offset + strikethrough->thickness
|
||||
);
|
||||
|
||||
ID2D1RectangleGeometry* pRectangleGeometry = nullptr;
|
||||
hr = pD2DFactory_->CreateRectangleGeometry(
|
||||
ID2D1RectangleGeometry* pRectangleGeometry = NULL;
|
||||
hr = pFactory_->CreateRectangleGeometry(
|
||||
&rect,
|
||||
&pRectangleGeometry
|
||||
);
|
||||
|
|
@ -360,10 +389,10 @@ namespace easy2d
|
|||
baselineOriginX, baselineOriginY
|
||||
);
|
||||
|
||||
ID2D1TransformedGeometry* pTransformedGeometry = nullptr;
|
||||
ID2D1TransformedGeometry* pTransformedGeometry = NULL;
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = pD2DFactory_->CreateTransformedGeometry(
|
||||
hr = pFactory_->CreateTransformedGeometry(
|
||||
pRectangleGeometry,
|
||||
&matrix,
|
||||
&pTransformedGeometry
|
||||
|
|
@ -392,13 +421,13 @@ namespace easy2d
|
|||
);
|
||||
}
|
||||
|
||||
SafeRelease(pRectangleGeometry);
|
||||
SafeRelease(pTransformedGeometry);
|
||||
DX::SafeRelease(pRectangleGeometry);
|
||||
DX::SafeRelease(pTransformedGeometry);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP TextRendererImpl::DrawInlineObject(
|
||||
STDMETHODIMP TextRenderer::DrawInlineObject(
|
||||
__maybenull void* clientDrawingContext,
|
||||
FLOAT originX,
|
||||
FLOAT originY,
|
||||
|
|
@ -417,12 +446,12 @@ namespace easy2d
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(unsigned long) TextRendererImpl::AddRef()
|
||||
STDMETHODIMP_(unsigned long) TextRenderer::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&cRefCount_);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(unsigned long) TextRendererImpl::Release()
|
||||
STDMETHODIMP_(unsigned long) TextRenderer::Release()
|
||||
{
|
||||
unsigned long newCount = InterlockedDecrement(&cRefCount_);
|
||||
|
||||
|
|
@ -435,7 +464,7 @@ namespace easy2d
|
|||
return newCount;
|
||||
}
|
||||
|
||||
STDMETHODIMP TextRendererImpl::IsPixelSnappingDisabled(
|
||||
STDMETHODIMP TextRenderer::IsPixelSnappingDisabled(
|
||||
__maybenull void* clientDrawingContext,
|
||||
__out BOOL* isDisabled)
|
||||
{
|
||||
|
|
@ -445,7 +474,7 @@ namespace easy2d
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP TextRendererImpl::GetCurrentTransform(
|
||||
STDMETHODIMP TextRenderer::GetCurrentTransform(
|
||||
__maybenull void* clientDrawingContext,
|
||||
__out DWRITE_MATRIX* transform)
|
||||
{
|
||||
|
|
@ -455,7 +484,7 @@ namespace easy2d
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP TextRendererImpl::GetPixelsPerDip(
|
||||
STDMETHODIMP TextRenderer::GetPixelsPerDip(
|
||||
__maybenull void* clientDrawingContext,
|
||||
__out FLOAT* pixelsPerDip)
|
||||
{
|
||||
|
|
@ -469,7 +498,7 @@ namespace easy2d
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP TextRendererImpl::QueryInterface(
|
||||
STDMETHODIMP TextRenderer::QueryInterface(
|
||||
IID const& riid,
|
||||
void** ppvObject)
|
||||
{
|
||||
|
|
@ -487,7 +516,7 @@ namespace easy2d
|
|||
}
|
||||
else
|
||||
{
|
||||
*ppvObject = nullptr;
|
||||
*ppvObject = NULL;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
|
|
@ -19,7 +19,8 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "d2dhelper.hpp"
|
||||
#include "helper.hpp"
|
||||
#include <dwrite.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
|
|
@ -29,9 +30,7 @@ namespace easy2d
|
|||
public:
|
||||
static E2D_API HRESULT Create(
|
||||
_Out_ ITextRenderer** ppTextRenderer,
|
||||
_In_ ID2D1Factory* pD2DFactory,
|
||||
_In_ ID2D1RenderTarget* pRT,
|
||||
_In_ ID2D1SolidColorBrush* pBrush
|
||||
_In_ ID2D1RenderTarget* pRT
|
||||
);
|
||||
|
||||
STDMETHOD_(void, SetTextStyle)(
|
||||
|
|
@ -43,5 +42,3 @@ namespace easy2d
|
|||
) PURE;
|
||||
};
|
||||
}
|
||||
|
||||
E2D_DECLARE_D2D_SMART_PTR(easy2d::ITextRenderer, D2DTextRendererPtr);
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - 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 "../core/IntrusivePtr.hpp"
|
||||
#include "../core/Color.h"
|
||||
#include "../math/vector.hpp"
|
||||
#include "../math/Rect.hpp"
|
||||
#include "../math/Matrix.hpp"
|
||||
#include <d2d1.h>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
// ComPtr<> is a smart pointer for COM
|
||||
template <typename _Ty>
|
||||
using ComPtr = IntrusivePtr<_Ty>;
|
||||
|
||||
|
||||
inline void IntrusivePtrAddRef(IUnknown* ptr)
|
||||
{
|
||||
if (ptr) { ptr->AddRef(); }
|
||||
}
|
||||
|
||||
inline void IntrusivePtrRelease(IUnknown* ptr)
|
||||
{
|
||||
if (ptr) { ptr->Release(); }
|
||||
}
|
||||
|
||||
namespace DX
|
||||
{
|
||||
template <typename T>
|
||||
inline void SafeRelease(T*& ptr)
|
||||
{
|
||||
if (ptr != nullptr)
|
||||
{
|
||||
ptr->Release();
|
||||
ptr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
inline D2D1_POINT_2F const& ConvertToPoint2F(math::Vec2 const& point)
|
||||
{
|
||||
return reinterpret_cast<D2D1_POINT_2F const&>(point);
|
||||
}
|
||||
|
||||
inline D2D1_SIZE_F const& ConvertToSizeF(math::Vec2 const& size)
|
||||
{
|
||||
return reinterpret_cast<D2D1_SIZE_F const&>(size);
|
||||
}
|
||||
|
||||
inline D2D1_RECT_F ConvertToRectF(math::Rect const& rect)
|
||||
{
|
||||
return D2D1_RECT_F{ rect.origin.x, rect.origin.y, rect.origin.x + rect.size.x, rect.origin.y + rect.size.y };
|
||||
}
|
||||
|
||||
inline D2D1_COLOR_F const& ConvertToColorF(Color const& color)
|
||||
{
|
||||
return reinterpret_cast<D2D1_COLOR_F const&>(color);
|
||||
}
|
||||
|
||||
inline D2D1_MATRIX_3X2_F const& ConvertToMatrix3x2F(math::Matrix const& matrix)
|
||||
{
|
||||
return reinterpret_cast<D2D1_MATRIX_3X2_F const&>(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.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -77,7 +77,6 @@
|
|||
#include "core/GeometryNode.h"
|
||||
#include "core/DebugNode.h"
|
||||
|
||||
#include "core/Factory.h"
|
||||
#include "core/Application.h"
|
||||
|
||||
|
||||
|
|
@ -90,7 +89,7 @@
|
|||
#include "math/ease.hpp"
|
||||
#include "math/vector.hpp"
|
||||
#include "math/rand.h"
|
||||
#include "math/Matrix.h"
|
||||
#include "math/Matrix.hpp"
|
||||
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,152 +0,0 @@
|
|||
// Copyright (c) 2016-2018 Easy2D - 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.
|
||||
|
||||
#include "Matrix.h"
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
Matrix::Matrix()
|
||||
: _11(1.f), _12(0.f)
|
||||
, _21(0.f), _22(1.f)
|
||||
, _31(0.f), _32(0.f)
|
||||
{
|
||||
}
|
||||
|
||||
Matrix::Matrix(float _11, float _12, float _21, float _22, float _31, float _32)
|
||||
: _11(_11), _12(_12), _21(_21), _22(_22), _31(_31), _32(_32)
|
||||
{
|
||||
}
|
||||
|
||||
Matrix::Matrix(const float* p)
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
m[i] = p[i];
|
||||
}
|
||||
|
||||
Matrix::Matrix(Matrix const& other)
|
||||
: _11(other._11), _12(other._12)
|
||||
, _21(other._21), _22(other._22)
|
||||
, _31(other._31), _32(other._32)
|
||||
{
|
||||
}
|
||||
|
||||
void Matrix::Identity()
|
||||
{
|
||||
_11 = 1.f; _12 = 0.f;
|
||||
_21 = 0.f; _12 = 1.f;
|
||||
_31 = 0.f; _32 = 0.f;
|
||||
}
|
||||
|
||||
Rect Matrix::Transform(const Rect & rect) const
|
||||
{
|
||||
Vec2 top_left = Transform(rect.GetLeftTop());
|
||||
Vec2 top_right = Transform(rect.GetRightTop());
|
||||
Vec2 bottom_left = Transform(rect.GetLeftBottom());
|
||||
Vec2 bottom_right = Transform(rect.GetRightBottom());
|
||||
|
||||
float left = std::min(std::min(top_left.x, top_right.x), std::min(bottom_left.x, bottom_right.x));
|
||||
float right = std::max(std::max(top_left.x, top_right.x), std::max(bottom_left.x, bottom_right.x));
|
||||
float top = std::min(std::min(top_left.y, top_right.y), std::min(bottom_left.y, bottom_right.y));
|
||||
float bottom = std::max(std::max(top_left.y, top_right.y), std::max(bottom_left.y, bottom_right.y));
|
||||
|
||||
return Rect{ left, top, (right - left), (bottom - top) };
|
||||
}
|
||||
|
||||
Matrix Matrix::Translation(const Vec2& v)
|
||||
{
|
||||
return Matrix(
|
||||
1.f, 0.f,
|
||||
0.f, 1.f,
|
||||
v.x, v.y
|
||||
);
|
||||
}
|
||||
|
||||
Matrix Matrix::Translation(
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
return Translation(Vec2(x, y));
|
||||
}
|
||||
|
||||
Matrix Matrix::Scaling(
|
||||
const Vec2& v,
|
||||
const Vec2& center)
|
||||
{
|
||||
return Matrix(
|
||||
v.x, 0.f,
|
||||
0.f, v.y,
|
||||
center.x - v.x * center.x,
|
||||
center.y - v.y * center.y
|
||||
);
|
||||
}
|
||||
|
||||
Matrix Matrix::Scaling(
|
||||
float x,
|
||||
float y,
|
||||
const Vec2& center)
|
||||
{
|
||||
return Scaling(Vec2(x, y), center);
|
||||
}
|
||||
|
||||
Matrix Matrix::Rotation(
|
||||
float angle,
|
||||
const Vec2& center)
|
||||
{
|
||||
float s = math::Sin(angle);
|
||||
float c = math::Cos(angle);
|
||||
return Matrix(
|
||||
c, s,
|
||||
-s, c,
|
||||
center.x * (1 - c) + center.y * s,
|
||||
center.y * (1 - c) - center.x * s
|
||||
);
|
||||
}
|
||||
|
||||
Matrix Matrix::Skewing(
|
||||
float angle_x,
|
||||
float angle_y,
|
||||
const Vec2& center)
|
||||
{
|
||||
float tx = math::Tan(angle_x);
|
||||
float ty = math::Tan(angle_y);
|
||||
return Matrix(
|
||||
1.f, -ty,
|
||||
-tx, 1.f,
|
||||
center.y * tx, center.x * ty
|
||||
);
|
||||
}
|
||||
|
||||
Matrix Matrix::Invert(Matrix const& matrix)
|
||||
{
|
||||
float det = 1.f / matrix.Determinant();
|
||||
|
||||
return Matrix(
|
||||
det * matrix._22,
|
||||
-det * matrix._12,
|
||||
-det * matrix._21,
|
||||
det * matrix._11,
|
||||
det * (matrix._21 * matrix._32 - matrix._22 * matrix._31),
|
||||
det * (matrix._12 * matrix._31 - matrix._11 * matrix._32)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -21,12 +21,13 @@
|
|||
#pragma once
|
||||
#include "vector.hpp"
|
||||
#include "Rect.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
namespace easy2d
|
||||
{
|
||||
namespace math
|
||||
{
|
||||
struct E2D_API Matrix
|
||||
struct Matrix
|
||||
{
|
||||
union
|
||||
{
|
||||
|
|
@ -44,13 +45,30 @@ namespace easy2d
|
|||
};
|
||||
};
|
||||
|
||||
Matrix();
|
||||
Matrix()
|
||||
: _11(1.f), _12(0.f)
|
||||
, _21(0.f), _22(1.f)
|
||||
, _31(0.f), _32(0.f)
|
||||
{
|
||||
}
|
||||
|
||||
Matrix(float _11, float _12, float _21, float _22, float _31, float _32);
|
||||
Matrix(float _11, float _12, float _21, float _22, float _31, float _32)
|
||||
: _11(_11), _12(_12), _21(_21), _22(_22), _31(_31), _32(_32)
|
||||
{
|
||||
}
|
||||
|
||||
Matrix(const float* p);
|
||||
Matrix(const float* p)
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
m[i] = p[i];
|
||||
}
|
||||
|
||||
Matrix(Matrix const& other);
|
||||
Matrix(Matrix const& other)
|
||||
: _11(other._11), _12(other._12)
|
||||
, _21(other._21), _22(other._22)
|
||||
, _31(other._31), _32(other._32)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Matrix(T const& other)
|
||||
|
|
@ -59,7 +77,12 @@ namespace easy2d
|
|||
m[i] = other[i];
|
||||
}
|
||||
|
||||
void Identity();
|
||||
inline void Identity()
|
||||
{
|
||||
_11 = 1.f; _12 = 0.f;
|
||||
_21 = 0.f; _12 = 1.f;
|
||||
_31 = 0.f; _32 = 0.f;
|
||||
}
|
||||
|
||||
inline Vec2 Transform(const Vec2& v) const
|
||||
{
|
||||
|
|
@ -69,7 +92,20 @@ namespace easy2d
|
|||
);
|
||||
}
|
||||
|
||||
Rect Transform(const Rect& rect) const;
|
||||
Rect Transform(const Rect & rect) const
|
||||
{
|
||||
Vec2 top_left = Transform(rect.GetLeftTop());
|
||||
Vec2 top_right = Transform(rect.GetRightTop());
|
||||
Vec2 bottom_left = Transform(rect.GetLeftBottom());
|
||||
Vec2 bottom_right = Transform(rect.GetRightBottom());
|
||||
|
||||
float left = std::min(std::min(top_left.x, top_right.x), std::min(bottom_left.x, bottom_right.x));
|
||||
float right = std::max(std::max(top_left.x, top_right.x), std::max(bottom_left.x, bottom_right.x));
|
||||
float top = std::min(std::min(top_left.y, top_right.y), std::min(bottom_left.y, bottom_right.y));
|
||||
float bottom = std::max(std::max(top_left.y, top_right.y), std::max(bottom_left.y, bottom_right.y));
|
||||
|
||||
return Rect{ left, top, (right - left), (bottom - top) };
|
||||
}
|
||||
|
||||
inline void Translate(const Vec2& v)
|
||||
{
|
||||
|
|
@ -107,46 +143,83 @@ namespace easy2d
|
|||
return 0 != Determinant();
|
||||
}
|
||||
|
||||
inline operator D2D1_MATRIX_3X2_F const& () const
|
||||
static inline Matrix Translation(const Vec2& v)
|
||||
{
|
||||
return reinterpret_cast<D2D1_MATRIX_3X2_F const&>(*this);
|
||||
return Matrix(
|
||||
1.f, 0.f,
|
||||
0.f, 1.f,
|
||||
v.x, v.y
|
||||
);
|
||||
}
|
||||
|
||||
inline operator D2D1_MATRIX_3X2_F& ()
|
||||
{
|
||||
return reinterpret_cast<D2D1_MATRIX_3X2_F&>(*this);
|
||||
}
|
||||
|
||||
static Matrix Translation(const Vec2& v);
|
||||
|
||||
static Matrix Translation(
|
||||
static inline Matrix Translation(
|
||||
float x,
|
||||
float y
|
||||
);
|
||||
float y)
|
||||
{
|
||||
return Translation(Vec2(x, y));
|
||||
}
|
||||
|
||||
static Matrix Scaling(
|
||||
static inline Matrix Scaling(
|
||||
const Vec2& v,
|
||||
const Vec2& center = Vec2()
|
||||
);
|
||||
const Vec2& center = Vec2())
|
||||
{
|
||||
return Matrix(
|
||||
v.x, 0.f,
|
||||
0.f, v.y,
|
||||
center.x - v.x * center.x,
|
||||
center.y - v.y * center.y
|
||||
);
|
||||
}
|
||||
|
||||
static Matrix Scaling(
|
||||
static inline Matrix Scaling(
|
||||
float x,
|
||||
float y,
|
||||
const Vec2& center = Vec2()
|
||||
);
|
||||
const Vec2& center = Vec2())
|
||||
{
|
||||
return Scaling(Vec2(x, y), center);
|
||||
}
|
||||
|
||||
static Matrix Rotation(
|
||||
static inline Matrix Rotation(
|
||||
float angle,
|
||||
const Vec2& center = Vec2()
|
||||
);
|
||||
const Vec2& center = Vec2())
|
||||
{
|
||||
float s = math::Sin(angle);
|
||||
float c = math::Cos(angle);
|
||||
return Matrix(
|
||||
c, s,
|
||||
-s, c,
|
||||
center.x * (1 - c) + center.y * s,
|
||||
center.y * (1 - c) - center.x * s
|
||||
);
|
||||
}
|
||||
|
||||
static Matrix Skewing(
|
||||
static inline Matrix Skewing(
|
||||
float angle_x,
|
||||
float angle_y,
|
||||
const Vec2& center = Vec2()
|
||||
);
|
||||
const Vec2& center = Vec2())
|
||||
{
|
||||
float tx = math::Tan(angle_x);
|
||||
float ty = math::Tan(angle_y);
|
||||
return Matrix(
|
||||
1.f, -ty,
|
||||
-tx, 1.f,
|
||||
center.y * tx, center.x * ty
|
||||
);
|
||||
}
|
||||
|
||||
static Matrix Invert(Matrix const& matrix);
|
||||
static inline Matrix Invert(Matrix const& matrix)
|
||||
{
|
||||
float det = 1.f / matrix.Determinant();
|
||||
|
||||
return Matrix(
|
||||
det * matrix._22,
|
||||
-det * matrix._12,
|
||||
-det * matrix._21,
|
||||
det * matrix._11,
|
||||
det * (matrix._21 * matrix._32 - matrix._22 * matrix._31),
|
||||
det * (matrix._12 * matrix._31 - matrix._11 * matrix._32)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ namespace easy2d
|
|||
namespace math
|
||||
{
|
||||
// 矩形
|
||||
struct E2D_API Rect
|
||||
struct Rect
|
||||
{
|
||||
Vec2 origin; // 左上角坐标
|
||||
Vec2 size; // 宽度和高度
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@
|
|||
// THE SOFTWARE.
|
||||
|
||||
#pragma once
|
||||
#include "../core/macros.h"
|
||||
#include "constants.hpp"
|
||||
#include <cmath>
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ namespace easy2d
|
|||
{
|
||||
namespace math
|
||||
{
|
||||
struct E2D_API Vec2
|
||||
struct Vec2
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
|
|
@ -81,6 +81,11 @@ namespace easy2d
|
|||
{
|
||||
return (x == other.x) && (y == other.y);
|
||||
}
|
||||
|
||||
inline bool operator!= (const Vec2& other) const
|
||||
{
|
||||
return (x != other.x) || (y != other.y);
|
||||
}
|
||||
};
|
||||
|
||||
using Point = Vec2;
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@
|
|||
#endif
|
||||
|
||||
#include "Transcoder.h"
|
||||
#include "../core/d2dhelper.hpp"
|
||||
#include "../core/modules.h"
|
||||
#include "../core/logs.h"
|
||||
#include "../DX/helper.hpp"
|
||||
#include <shlwapi.h>
|
||||
|
||||
namespace easy2d
|
||||
|
|
@ -53,7 +53,7 @@ namespace easy2d
|
|||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
IntrusivePtr<IMFSourceReader> reader;
|
||||
ComPtr<IMFSourceReader> reader;
|
||||
|
||||
hr = modules::MediaFoundation::Get().MFCreateSourceReaderFromURL(
|
||||
file_path.c_str(),
|
||||
|
|
@ -73,9 +73,9 @@ namespace easy2d
|
|||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
IntrusivePtr<IStream> stream;
|
||||
IntrusivePtr<IMFByteStream> byte_stream;
|
||||
IntrusivePtr<IMFSourceReader> reader;
|
||||
ComPtr<IStream> stream;
|
||||
ComPtr<IMFByteStream> byte_stream;
|
||||
ComPtr<IMFSourceReader> reader;
|
||||
|
||||
LPVOID buffer;
|
||||
DWORD buffer_size;
|
||||
|
|
@ -119,8 +119,8 @@ namespace easy2d
|
|||
HRESULT hr = S_OK;
|
||||
DWORD max_stream_size = 0;
|
||||
|
||||
IntrusivePtr<IMFMediaType> partial_type;
|
||||
IntrusivePtr<IMFMediaType> uncompressed_type;
|
||||
ComPtr<IMFMediaType> partial_type;
|
||||
ComPtr<IMFMediaType> uncompressed_type;
|
||||
|
||||
hr = modules::MediaFoundation::Get().MFCreateMediaType(&partial_type);
|
||||
|
||||
|
|
@ -200,8 +200,8 @@ namespace easy2d
|
|||
DWORD position = 0;
|
||||
BYTE* data = new (std::nothrow) BYTE[max_stream_size];
|
||||
|
||||
IntrusivePtr<IMFSample> sample;
|
||||
IntrusivePtr<IMFMediaBuffer> buffer;
|
||||
ComPtr<IMFSample> sample;
|
||||
ComPtr<IMFMediaBuffer> buffer;
|
||||
|
||||
if (data == nullptr)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue