d3d11 support
This commit is contained in:
parent
1f8b0bb058
commit
074af87127
|
|
@ -216,7 +216,7 @@ int main()
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,10 @@
|
||||||
<ClInclude Include="..\..\src\core\closure.hpp" />
|
<ClInclude Include="..\..\src\core\closure.hpp" />
|
||||||
<ClInclude Include="..\..\src\core\Color.h" />
|
<ClInclude Include="..\..\src\core\Color.h" />
|
||||||
<ClInclude Include="..\..\src\core\config.h" />
|
<ClInclude Include="..\..\src\core\config.h" />
|
||||||
<ClInclude Include="..\..\src\core\d2dhelper.hpp" />
|
|
||||||
<ClInclude Include="..\..\src\core\DebugNode.h" />
|
<ClInclude Include="..\..\src\core\DebugNode.h" />
|
||||||
<ClInclude Include="..\..\src\core\Event.hpp" />
|
<ClInclude Include="..\..\src\core\Event.hpp" />
|
||||||
<ClInclude Include="..\..\src\core\EventDispatcher.h" />
|
<ClInclude Include="..\..\src\core\EventDispatcher.h" />
|
||||||
<ClInclude Include="..\..\src\core\EventListener.h" />
|
<ClInclude Include="..\..\src\core\EventListener.h" />
|
||||||
<ClInclude Include="..\..\src\core\Factory.h" />
|
|
||||||
<ClInclude Include="..\..\src\core\Font.hpp" />
|
<ClInclude Include="..\..\src\core\Font.hpp" />
|
||||||
<ClInclude Include="..\..\src\core\Frames.h" />
|
<ClInclude Include="..\..\src\core\Frames.h" />
|
||||||
<ClInclude Include="..\..\src\core\Application.h" />
|
<ClInclude Include="..\..\src\core\Application.h" />
|
||||||
|
|
@ -47,16 +45,20 @@
|
||||||
<ClInclude Include="..\..\src\core\Task.h" />
|
<ClInclude Include="..\..\src\core\Task.h" />
|
||||||
<ClInclude Include="..\..\src\core\TaskManager.h" />
|
<ClInclude Include="..\..\src\core\TaskManager.h" />
|
||||||
<ClInclude Include="..\..\src\core\Text.h" />
|
<ClInclude Include="..\..\src\core\Text.h" />
|
||||||
<ClInclude Include="..\..\src\core\TextRenderer.h" />
|
|
||||||
<ClInclude Include="..\..\src\core\TextStyle.hpp" />
|
<ClInclude Include="..\..\src\core\TextStyle.hpp" />
|
||||||
<ClInclude Include="..\..\src\core\time.h" />
|
<ClInclude Include="..\..\src\core\time.h" />
|
||||||
<ClInclude Include="..\..\src\core\Transform.hpp" />
|
<ClInclude Include="..\..\src\core\Transform.hpp" />
|
||||||
<ClInclude Include="..\..\src\core\Transition.h" />
|
<ClInclude Include="..\..\src\core\Transition.h" />
|
||||||
<ClInclude Include="..\..\src\core\window.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\easy2d.h" />
|
||||||
<ClInclude Include="..\..\src\math\constants.hpp" />
|
<ClInclude Include="..\..\src\math\constants.hpp" />
|
||||||
<ClInclude Include="..\..\src\math\ease.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\rand.h" />
|
||||||
<ClInclude Include="..\..\src\math\Rect.hpp" />
|
<ClInclude Include="..\..\src\math\Rect.hpp" />
|
||||||
<ClInclude Include="..\..\src\math\scalar.hpp" />
|
<ClInclude Include="..\..\src\math\scalar.hpp" />
|
||||||
|
|
@ -83,7 +85,6 @@
|
||||||
<ClCompile Include="..\..\src\core\DebugNode.cpp" />
|
<ClCompile Include="..\..\src\core\DebugNode.cpp" />
|
||||||
<ClCompile Include="..\..\src\core\EventDispatcher.cpp" />
|
<ClCompile Include="..\..\src\core\EventDispatcher.cpp" />
|
||||||
<ClCompile Include="..\..\src\core\EventListener.cpp" />
|
<ClCompile Include="..\..\src\core\EventListener.cpp" />
|
||||||
<ClCompile Include="..\..\src\core\Factory.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\core\Frames.cpp" />
|
<ClCompile Include="..\..\src\core\Frames.cpp" />
|
||||||
<ClCompile Include="..\..\src\core\Application.cpp" />
|
<ClCompile Include="..\..\src\core\Application.cpp" />
|
||||||
<ClCompile Include="..\..\src\core\Geometry.cpp" />
|
<ClCompile Include="..\..\src\core\Geometry.cpp" />
|
||||||
|
|
@ -102,11 +103,12 @@
|
||||||
<ClCompile Include="..\..\src\core\Task.cpp" />
|
<ClCompile Include="..\..\src\core\Task.cpp" />
|
||||||
<ClCompile Include="..\..\src\core\TaskManager.cpp" />
|
<ClCompile Include="..\..\src\core\TaskManager.cpp" />
|
||||||
<ClCompile Include="..\..\src\core\Text.cpp" />
|
<ClCompile Include="..\..\src\core\Text.cpp" />
|
||||||
<ClCompile Include="..\..\src\core\TextRenderer.cpp" />
|
|
||||||
<ClCompile Include="..\..\src\core\time.cpp" />
|
<ClCompile Include="..\..\src\core\time.cpp" />
|
||||||
<ClCompile Include="..\..\src\core\Transition.cpp" />
|
<ClCompile Include="..\..\src\core\Transition.cpp" />
|
||||||
<ClCompile Include="..\..\src\core\window.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\math\rand.cpp" />
|
||||||
<ClCompile Include="..\..\src\ui\Button.cpp" />
|
<ClCompile Include="..\..\src\ui\Button.cpp" />
|
||||||
<ClCompile Include="..\..\src\ui\Menu.cpp" />
|
<ClCompile Include="..\..\src\ui\Menu.cpp" />
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@
|
||||||
<Filter Include="ui">
|
<Filter Include="ui">
|
||||||
<UniqueIdentifier>{07b6d541-4a1b-472a-aae0-daf9d082fe84}</UniqueIdentifier>
|
<UniqueIdentifier>{07b6d541-4a1b-472a-aae0-daf9d082fe84}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="dx">
|
||||||
|
<UniqueIdentifier>{a9793a75-3212-4e31-a443-b23f18a1e136}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\..\src\easy2d.h" />
|
<ClInclude Include="..\..\src\easy2d.h" />
|
||||||
|
|
@ -64,9 +67,6 @@
|
||||||
<ClInclude Include="..\..\src\core\Text.h">
|
<ClInclude Include="..\..\src\core\Text.h">
|
||||||
<Filter>core</Filter>
|
<Filter>core</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\core\TextRenderer.h">
|
|
||||||
<Filter>core</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\src\core\time.h">
|
<ClInclude Include="..\..\src\core\time.h">
|
||||||
<Filter>core</Filter>
|
<Filter>core</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
@ -154,9 +154,6 @@
|
||||||
<ClInclude Include="..\..\src\math\constants.hpp">
|
<ClInclude Include="..\..\src\math\constants.hpp">
|
||||||
<Filter>math</Filter>
|
<Filter>math</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\core\Factory.h">
|
|
||||||
<Filter>core</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\src\core\EventDispatcher.h">
|
<ClInclude Include="..\..\src\core\EventDispatcher.h">
|
||||||
<Filter>core</Filter>
|
<Filter>core</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
@ -169,9 +166,6 @@
|
||||||
<ClInclude Include="..\..\src\core\helper.hpp">
|
<ClInclude Include="..\..\src\core\helper.hpp">
|
||||||
<Filter>core</Filter>
|
<Filter>core</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\core\d2dhelper.hpp">
|
|
||||||
<Filter>core</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\src\core\keys.hpp">
|
<ClInclude Include="..\..\src\core\keys.hpp">
|
||||||
<Filter>core</Filter>
|
<Filter>core</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
@ -208,9 +202,6 @@
|
||||||
<ClInclude Include="..\..\src\core\ActionHelper.h">
|
<ClInclude Include="..\..\src\core\ActionHelper.h">
|
||||||
<Filter>core</Filter>
|
<Filter>core</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\math\Matrix.h">
|
|
||||||
<Filter>math</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\..\src\core\Array.h">
|
<ClInclude Include="..\..\src\core\Array.h">
|
||||||
<Filter>core</Filter>
|
<Filter>core</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
@ -220,6 +211,24 @@
|
||||||
<ClInclude Include="..\..\src\core\Action.h">
|
<ClInclude Include="..\..\src\core\Action.h">
|
||||||
<Filter>core</Filter>
|
<Filter>core</Filter>
|
||||||
</ClInclude>
|
</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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\src\core\Animation.cpp">
|
<ClCompile Include="..\..\src\core\Animation.cpp">
|
||||||
|
|
@ -264,9 +273,6 @@
|
||||||
<ClCompile Include="..\..\src\core\Text.cpp">
|
<ClCompile Include="..\..\src\core\Text.cpp">
|
||||||
<Filter>core</Filter>
|
<Filter>core</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\core\TextRenderer.cpp">
|
|
||||||
<Filter>core</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\src\core\time.cpp">
|
<ClCompile Include="..\..\src\core\time.cpp">
|
||||||
<Filter>core</Filter>
|
<Filter>core</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
@ -327,9 +333,6 @@
|
||||||
<ClCompile Include="..\..\src\core\Frames.cpp">
|
<ClCompile Include="..\..\src\core\Frames.cpp">
|
||||||
<Filter>core</Filter>
|
<Filter>core</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\core\Factory.cpp">
|
|
||||||
<Filter>core</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\src\core\EventDispatcher.cpp">
|
<ClCompile Include="..\..\src\core\EventDispatcher.cpp">
|
||||||
<Filter>core</Filter>
|
<Filter>core</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
@ -351,11 +354,17 @@
|
||||||
<ClCompile Include="..\..\src\core\ActionGroup.cpp">
|
<ClCompile Include="..\..\src\core\ActionGroup.cpp">
|
||||||
<Filter>core</Filter>
|
<Filter>core</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\math\Matrix.cpp">
|
|
||||||
<Filter>math</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\..\src\core\Action.cpp">
|
<ClCompile Include="..\..\src\core\Action.cpp">
|
||||||
<Filter>core</Filter>
|
<Filter>core</Filter>
|
||||||
</ClCompile>
|
</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>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -13,9 +13,11 @@ public:
|
||||||
{
|
{
|
||||||
// 创建文字节点
|
// 创建文字节点
|
||||||
easy2d::TextPtr text = new easy2d::Text(L"Hello Easy2D!");
|
easy2d::TextPtr text = new easy2d::Text(L"Hello Easy2D!");
|
||||||
// 修改节点位置
|
// 设置节点大小为文字布局大小
|
||||||
|
text->SetSize(text->GetLayoutSize());
|
||||||
|
// 修改节点位置, 使节点在屏幕上居中
|
||||||
text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2);
|
text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2);
|
||||||
// 修改节点锚点, 使节点在屏幕上居中
|
// 修改节点锚点, 使文字中心对齐屏幕中心
|
||||||
text->SetAnchor(0.5, 0.5);
|
text->SetAnchor(0.5, 0.5);
|
||||||
// 添加到场景中
|
// 添加到场景中
|
||||||
this->AddChild(text);
|
this->AddChild(text);
|
||||||
|
|
@ -46,7 +48,7 @@ int main()
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@ public:
|
||||||
{
|
{
|
||||||
// 创建文本
|
// 创建文本
|
||||||
TextPtr text = new Text(L"Hello Easy2D!");
|
TextPtr text = new Text(L"Hello Easy2D!");
|
||||||
|
// 设置节点大小为文字布局大小
|
||||||
|
text->SetSize(text->GetLayoutSize());
|
||||||
// 让文本显示在屏幕中央
|
// 让文本显示在屏幕中央
|
||||||
text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2);
|
text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2);
|
||||||
text->SetAnchor(0.5, 0.5);
|
text->SetAnchor(0.5, 0.5);
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,8 @@ public:
|
||||||
|
|
||||||
// 创建说明文字
|
// 创建说明文字
|
||||||
TextPtr text = new Text(L"按上下左右键移动\n按鼠标左键旋转\n点击鼠标右键隐藏");
|
TextPtr text = new Text(L"按上下左右键移动\n按鼠标左键旋转\n点击鼠标右键隐藏");
|
||||||
|
// 设置节点大小为文字布局大小
|
||||||
|
text->SetSize(text->GetLayoutSize());
|
||||||
// 设置文字位置
|
// 设置文字位置
|
||||||
text->SetAnchor(0.5f, 0.5f);
|
text->SetAnchor(0.5f, 0.5f);
|
||||||
text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT - 50);
|
text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT - 50);
|
||||||
|
|
|
||||||
|
|
@ -33,18 +33,15 @@ public:
|
||||||
|
|
||||||
// 创建说明文字
|
// 创建说明文字
|
||||||
TextPtr intro_text = new Text(L"按上下键调整音量\n按空格键暂停或继续");
|
TextPtr intro_text = new Text(L"按上下键调整音量\n按空格键暂停或继续");
|
||||||
intro_text->SetAnchor(0.5f, 0.5f);
|
intro_text->SetPosition(WINDOW_WIDTH / 2 - 80, WINDOW_HEIGHT / 2 - 50);
|
||||||
intro_text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2 - 50);
|
|
||||||
|
|
||||||
// 创建音量文字
|
// 创建音量文字
|
||||||
volume_text = new Text(L"当前音量:");
|
volume_text = new Text(L"当前音量:");
|
||||||
volume_text->SetAnchor(0.5f, 0.5f);
|
volume_text->SetPosition(WINDOW_WIDTH / 2 - 80, WINDOW_HEIGHT / 2 + 30);
|
||||||
volume_text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2 + 30);
|
|
||||||
|
|
||||||
// 创建状态文字
|
// 创建状态文字
|
||||||
state_text = new Text(L"当前状态:");
|
state_text = new Text(L"当前状态:");
|
||||||
state_text->SetAnchor(0.5f, 0.5f);
|
state_text->SetPosition(WINDOW_WIDTH / 2 - 80, WINDOW_HEIGHT / 2 + 60);
|
||||||
state_text->SetPosition(WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2 + 60);
|
|
||||||
|
|
||||||
// 添加到场景
|
// 添加到场景
|
||||||
this->AddChild(intro_text);
|
this->AddChild(intro_text);
|
||||||
|
|
|
||||||
|
|
@ -76,7 +76,7 @@ int main()
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
#include "modules.h"
|
#include "modules.h"
|
||||||
#include "Factory.h"
|
#include "render.h"
|
||||||
#include "Event.hpp"
|
#include "Event.hpp"
|
||||||
#include "Scene.h"
|
#include "Scene.h"
|
||||||
#include "DebugNode.h"
|
#include "DebugNode.h"
|
||||||
|
|
@ -37,7 +37,6 @@ namespace easy2d
|
||||||
Application::Application(String const& app_name)
|
Application::Application(String const& app_name)
|
||||||
: end_(true)
|
: end_(true)
|
||||||
, inited_(false)
|
, inited_(false)
|
||||||
, debug_(false)
|
|
||||||
, curr_scene_(nullptr)
|
, curr_scene_(nullptr)
|
||||||
, next_scene_(nullptr)
|
, next_scene_(nullptr)
|
||||||
, transition_(nullptr)
|
, transition_(nullptr)
|
||||||
|
|
@ -56,44 +55,6 @@ namespace easy2d
|
||||||
|
|
||||||
void Application::Init(const Options& options)
|
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(
|
ThrowIfFailed(
|
||||||
Window::Instance().Init(
|
Window::Instance().Init(
|
||||||
options.title,
|
options.title,
|
||||||
|
|
@ -101,30 +62,26 @@ namespace easy2d
|
||||||
options.height,
|
options.height,
|
||||||
options.icon,
|
options.icon,
|
||||||
options.fullscreen,
|
options.fullscreen,
|
||||||
Application::WndProc,
|
Application::WndProc
|
||||||
debug_
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
HWND hwnd = Window::Instance().GetHandle();
|
HWND hwnd = Window::Instance().GetHandle();
|
||||||
|
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
RenderSystem::Instance().Init(
|
Renderer::Instance().Init(hwnd)
|
||||||
hwnd,
|
|
||||||
options.vsync,
|
|
||||||
debug_
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Renderer::Instance().SetClearColor(options.clear_color);
|
||||||
|
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
Input::Instance().Init(
|
Input::Instance().Init(
|
||||||
hwnd,
|
hwnd
|
||||||
debug_
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
Audio::Instance().Init(debug_)
|
Audio::Instance().Init()
|
||||||
);
|
);
|
||||||
|
|
||||||
OnStart();
|
OnStart();
|
||||||
|
|
@ -173,9 +130,8 @@ namespace easy2d
|
||||||
curr_scene_.Reset();
|
curr_scene_.Reset();
|
||||||
|
|
||||||
Audio::Instance().Destroy();
|
Audio::Instance().Destroy();
|
||||||
RenderSystem::Instance().Destroy();
|
Renderer::Instance().Destroy();
|
||||||
Window::Instance().Destroy();
|
Window::Instance().Destroy();
|
||||||
Factory::Instance().Destroy();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,16 +207,14 @@ namespace easy2d
|
||||||
if (next_scene_)
|
if (next_scene_)
|
||||||
next_scene_->Update(dt);
|
next_scene_->Update(dt);
|
||||||
|
|
||||||
if (debug_)
|
if (DebugNode::IsShown())
|
||||||
DebugNode::Instance().Update(dt);
|
DebugNode::Instance().Update(dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::Render(HWND hwnd)
|
void Application::Render(HWND hwnd)
|
||||||
{
|
{
|
||||||
auto& rt = RenderSystem::Instance();
|
|
||||||
|
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
rt.BeginDraw(hwnd)
|
Renderer::Instance().BeginDraw()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (transition_)
|
if (transition_)
|
||||||
|
|
@ -272,16 +226,50 @@ namespace easy2d
|
||||||
curr_scene_->Render();
|
curr_scene_->Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug_)
|
if (DebugNode::IsShown())
|
||||||
DebugNode::Instance().Render();
|
DebugNode::Instance().Render();
|
||||||
|
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
rt.EndDraw()
|
Renderer::Instance().EndDraw()
|
||||||
);
|
);
|
||||||
|
|
||||||
::InvalidateRect(hwnd, NULL, FALSE);
|
::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)
|
LRESULT CALLBACK Application::WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||||
{
|
{
|
||||||
Application * app = reinterpret_cast<Application*>(
|
Application * app = reinterpret_cast<Application*>(
|
||||||
|
|
@ -363,10 +351,7 @@ namespace easy2d
|
||||||
UINT width = LOWORD(lparam);
|
UINT width = LOWORD(lparam);
|
||||||
UINT height = HIWORD(lparam);
|
UINT height = HIWORD(lparam);
|
||||||
|
|
||||||
// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染
|
Renderer::Instance().GetDeviceResources()->SetLogicalSize(Size{ (float)width, (float)height });
|
||||||
// 目标的大小。它可能会调用失败,但是这里可以忽略有可能的
|
|
||||||
// 错误,因为这个错误将在下一次调用 EndDraw 时产生
|
|
||||||
RenderSystem::Instance().Resize(width, height);
|
|
||||||
|
|
||||||
if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam)
|
if (SIZE_MAXHIDE == wparam || SIZE_MINIMIZED == wparam)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
#include "include-forwards.h"
|
#include "include-forwards.h"
|
||||||
#include "time.h"
|
#include "time.h"
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
#include "render.h"
|
|
||||||
#include "input.h"
|
#include "input.h"
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
|
|
||||||
|
|
@ -30,22 +29,22 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
struct Options
|
struct Options
|
||||||
{
|
{
|
||||||
String title; // 标题
|
String title; // 标题
|
||||||
int width; // 宽度
|
int width; // 宽度
|
||||||
int height; // 高度
|
int height; // 高度
|
||||||
LPCWSTR icon; // 图标
|
LPCWSTR icon; // 图标
|
||||||
bool vsync; // 垂直同步
|
Color clear_color; // 清屏颜色
|
||||||
bool fullscreen; // 全屏模式
|
bool vsync; // 垂直同步
|
||||||
bool debug; // 调试模式
|
bool fullscreen; // 全屏模式
|
||||||
|
|
||||||
Options()
|
Options()
|
||||||
: title(L"Easy2D Game")
|
: title(L"Easy2D Game")
|
||||||
, width(640)
|
, width(640)
|
||||||
, height(480)
|
, height(480)
|
||||||
, icon(nullptr)
|
, icon(nullptr)
|
||||||
|
, clear_color(Color::Black)
|
||||||
, vsync(true)
|
, vsync(true)
|
||||||
, fullscreen(false)
|
, fullscreen(false)
|
||||||
, debug(false)
|
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -105,6 +104,9 @@ namespace easy2d
|
||||||
float scale_factor
|
float scale_factor
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 分配控制台
|
||||||
|
static void AllocConsole();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Render(HWND);
|
void Render(HWND);
|
||||||
|
|
||||||
|
|
@ -115,7 +117,6 @@ namespace easy2d
|
||||||
private:
|
private:
|
||||||
bool end_;
|
bool end_;
|
||||||
bool inited_;
|
bool inited_;
|
||||||
bool debug_;
|
|
||||||
float time_scale_;
|
float time_scale_;
|
||||||
String app_name_;
|
String app_name_;
|
||||||
ScenePtr curr_scene_;
|
ScenePtr curr_scene_;
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
#include "Geometry.h"
|
#include "Geometry.h"
|
||||||
#include "Factory.h"
|
#include "render.h"
|
||||||
|
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
{
|
{
|
||||||
|
|
@ -31,37 +31,30 @@ namespace easy2d
|
||||||
: cache_expired_(false)
|
: cache_expired_(false)
|
||||||
, stroke_width_(1.0f)
|
, stroke_width_(1.0f)
|
||||||
{
|
{
|
||||||
|
auto ctx = Renderer::Instance().GetDeviceResources()->GetD2DDeviceContext();
|
||||||
|
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
RenderSystem::Instance().CreateBitmapRenderTarget(render_target_)
|
ctx->CreateCompatibleRenderTarget(&render_target_)
|
||||||
);
|
);
|
||||||
|
|
||||||
auto properties = D2D1::BrushProperties();
|
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
render_target_->CreateSolidColorBrush(
|
render_target_->CreateSolidColorBrush(
|
||||||
D2D1::ColorF(0, 0, 0, 0),
|
D2D1::ColorF(0, 0, 0, 0),
|
||||||
properties,
|
D2D1::BrushProperties(),
|
||||||
&fill_brush_)
|
&fill_brush_)
|
||||||
);
|
);
|
||||||
|
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
render_target_->CreateSolidColorBrush(
|
render_target_->CreateSolidColorBrush(
|
||||||
D2D1::ColorF(Color::White),
|
D2D1::ColorF(Color::White),
|
||||||
properties,
|
D2D1::BrushProperties(),
|
||||||
&stroke_brush_)
|
&stroke_brush_)
|
||||||
);
|
);
|
||||||
|
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
render_target_->CreateSolidColorBrush(
|
ITextRenderer::Create(
|
||||||
D2D1::ColorF(Color::White),
|
&text_renderer_,
|
||||||
properties,
|
render_target_.Get()
|
||||||
&text_brush_)
|
|
||||||
);
|
|
||||||
|
|
||||||
ThrowIfFailed(
|
|
||||||
Factory::Instance().CreateTextRenderer(
|
|
||||||
text_renderer_,
|
|
||||||
render_target_,
|
|
||||||
text_brush_
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -105,18 +98,18 @@ namespace easy2d
|
||||||
|
|
||||||
if (bitmap_cached_)
|
if (bitmap_cached_)
|
||||||
{
|
{
|
||||||
RenderSystem::Instance().DrawBitmap(bitmap_cached_);
|
Renderer::Instance().DrawBitmap(bitmap_cached_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::SetStrokeColor(Color const& color)
|
void Canvas::SetStrokeColor(Color const& color)
|
||||||
{
|
{
|
||||||
stroke_brush_->SetColor(ToD2dColorF(color));
|
stroke_brush_->SetColor(DX::ConvertToColorF(color));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::SetFillColor(Color const& color)
|
void Canvas::SetFillColor(Color const& color)
|
||||||
{
|
{
|
||||||
fill_brush_->SetColor(ToD2dColorF(color));
|
fill_brush_->SetColor(DX::ConvertToColorF(color));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::SetStrokeWidth(float width)
|
void Canvas::SetStrokeWidth(float width)
|
||||||
|
|
@ -126,7 +119,7 @@ namespace easy2d
|
||||||
|
|
||||||
void Canvas::SetOutlineJoinStyle(StrokeStyle outline_join)
|
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)
|
void Canvas::SetTextStyle(Font const& font, TextStyle const & text_style)
|
||||||
|
|
@ -135,12 +128,15 @@ namespace easy2d
|
||||||
text_style_ = text_style;
|
text_style_ = text_style;
|
||||||
|
|
||||||
text_renderer_->SetTextStyle(
|
text_renderer_->SetTextStyle(
|
||||||
ToD2dColorF(text_style_.color),
|
DX::ConvertToColorF(text_style_.color),
|
||||||
text_style_.outline,
|
text_style_.outline,
|
||||||
ToD2dColorF(text_style_.outline_color),
|
DX::ConvertToColorF(text_style_.outline_color),
|
||||||
text_style_.outline_width,
|
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
|
Color Canvas::GetStrokeColor() const
|
||||||
|
|
@ -162,7 +158,7 @@ namespace easy2d
|
||||||
|
|
||||||
void Canvas::SetBrushTransform(Matrix const & transform)
|
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)
|
void Canvas::DrawLine(const Point & begin, const Point & end)
|
||||||
|
|
@ -258,7 +254,7 @@ namespace easy2d
|
||||||
D2D1::RectF(0, 0, image->GetWidth(), image->GetHeight()),
|
D2D1::RectF(0, 0, image->GetWidth(), image->GetHeight()),
|
||||||
opacity,
|
opacity,
|
||||||
D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
|
D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
|
||||||
ToD2dRectF(image->GetCropRect())
|
DX::ConvertToRectF(image->GetCropRect())
|
||||||
);
|
);
|
||||||
cache_expired_ = true;
|
cache_expired_ = true;
|
||||||
}
|
}
|
||||||
|
|
@ -269,23 +265,25 @@ namespace easy2d
|
||||||
if (text.empty())
|
if (text.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
D2DTextFormatPtr text_format;
|
if (!text_format_)
|
||||||
ThrowIfFailed(
|
{
|
||||||
Factory::Instance().CreateTextFormat(
|
ThrowIfFailed(
|
||||||
text_format,
|
Renderer::Instance().GetDeviceResources()->CreateTextFormat(
|
||||||
text_font_,
|
text_format_,
|
||||||
text_style_
|
text_font_,
|
||||||
)
|
text_style_
|
||||||
);
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
D2DTextLayoutPtr text_layout;
|
ComPtr<IDWriteTextLayout> text_layout;
|
||||||
Size layout_size;
|
Size layout_size;
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
Factory::Instance().CreateTextLayout(
|
Renderer::Instance().GetDeviceResources()->CreateTextLayout(
|
||||||
text_layout,
|
text_layout,
|
||||||
layout_size,
|
layout_size,
|
||||||
text,
|
text,
|
||||||
text_format,
|
text_format_,
|
||||||
text_style_
|
text_style_
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
@ -390,14 +388,14 @@ namespace easy2d
|
||||||
current_geometry_ = nullptr;
|
current_geometry_ = nullptr;
|
||||||
|
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
Factory::Instance().CreatePathGeometry(current_geometry_)
|
Renderer::Instance().GetDeviceResources()->GetD2DFactory()->CreatePathGeometry(¤t_geometry_)
|
||||||
);
|
);
|
||||||
|
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
current_geometry_->Open(¤t_sink_)
|
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)
|
void Canvas::EndPath(bool closed)
|
||||||
|
|
@ -415,7 +413,7 @@ namespace easy2d
|
||||||
void Canvas::AddLine(Point const & point)
|
void Canvas::AddLine(Point const & point)
|
||||||
{
|
{
|
||||||
if (current_sink_)
|
if (current_sink_)
|
||||||
current_sink_->AddLine(ToD2dPoint2F(point));
|
current_sink_->AddLine(DX::ConvertToPoint2F(point));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::AddLines(Array<Point> const& points)
|
void Canvas::AddLines(Array<Point> const& points)
|
||||||
|
|
@ -435,9 +433,9 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
current_sink_->AddBezier(
|
current_sink_->AddBezier(
|
||||||
D2D1::BezierSegment(
|
D2D1::BezierSegment(
|
||||||
ToD2dPoint2F(point1),
|
DX::ConvertToPoint2F(point1),
|
||||||
ToD2dPoint2F(point2),
|
DX::ConvertToPoint2F(point2),
|
||||||
ToD2dPoint2F(point3)
|
DX::ConvertToPoint2F(point3)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -449,8 +447,8 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
current_sink_->AddArc(
|
current_sink_->AddArc(
|
||||||
D2D1::ArcSegment(
|
D2D1::ArcSegment(
|
||||||
ToD2dPoint2F(point),
|
DX::ConvertToPoint2F(point),
|
||||||
ToD2dSizeF(radius),
|
DX::ConvertToSizeF(radius),
|
||||||
rotation,
|
rotation,
|
||||||
clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,
|
clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,
|
||||||
is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE
|
is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE
|
||||||
|
|
@ -492,7 +490,7 @@ namespace easy2d
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
D2DBitmapPtr const& easy2d::Canvas::GetBitmap() const
|
ComPtr<ID2D1Bitmap> const& easy2d::Canvas::GetBitmap() const
|
||||||
{
|
{
|
||||||
if (cache_expired_)
|
if (cache_expired_)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
#include "Node.h"
|
#include "Node.h"
|
||||||
#include "Font.hpp"
|
#include "Font.hpp"
|
||||||
#include "TextStyle.hpp"
|
#include "TextStyle.hpp"
|
||||||
#include "TextRenderer.h"
|
#include "../DX/TextRenderer.h"
|
||||||
|
|
||||||
#undef DrawText
|
#undef DrawText
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
// »²¼
|
// »²¼
|
||||||
class E2D_API Canvas
|
class E2D_API Canvas
|
||||||
: public Node
|
: public VisualNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Canvas();
|
Canvas();
|
||||||
|
|
@ -221,22 +221,23 @@ namespace easy2d
|
||||||
void OnRender() override;
|
void OnRender() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
D2DBitmapPtr const& GetBitmap() const;
|
ComPtr<ID2D1Bitmap> const& GetBitmap() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float stroke_width_;
|
float stroke_width_;
|
||||||
Font text_font_;
|
Font text_font_;
|
||||||
TextStyle text_style_;
|
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_;
|
ComPtr<ID2D1PathGeometry> current_geometry_;
|
||||||
mutable D2DBitmapPtr bitmap_cached_;
|
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 easy2d
|
||||||
{
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
bool show = false;
|
||||||
|
}
|
||||||
|
|
||||||
DebugNode::DebugNode()
|
DebugNode::DebugNode()
|
||||||
{
|
{
|
||||||
debug_text_ = new Text();
|
debug_text_ = new Text();
|
||||||
|
|
@ -67,16 +72,14 @@ namespace easy2d
|
||||||
|
|
||||||
void DebugNode::OnRender()
|
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));
|
Renderer::Instance().GetDeviceResources()->GetD2DDeviceContext()->FillRoundedRectangle(
|
||||||
|
|
||||||
rt.GetRenderTarget()->FillRoundedRectangle(
|
|
||||||
D2D1::RoundedRect(
|
D2D1::RoundedRect(
|
||||||
D2D1_RECT_F{ 10, 10, 200, 120 },
|
D2D1_RECT_F{ 10, 10, 200, 120 },
|
||||||
6.f,
|
6.f,
|
||||||
6.f),
|
6.f),
|
||||||
rt.GetSolidBrush().Get()
|
Renderer::Instance().GetSolidColorBrush()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,9 +108,9 @@ namespace easy2d
|
||||||
ss << "Objects: " << Object::__GetTracingObjects().size() << std::endl;
|
ss << "Objects: " << Object::__GetTracingObjects().size() << std::endl;
|
||||||
#endif
|
#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;
|
PROCESS_MEMORY_COUNTERS_EX pmc;
|
||||||
GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc));
|
GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc));
|
||||||
|
|
@ -119,4 +122,19 @@ namespace easy2d
|
||||||
debug_text_->SetText(ss.str());
|
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
|
namespace easy2d
|
||||||
{
|
{
|
||||||
class E2D_API DebugNode
|
class E2D_API DebugNode
|
||||||
: public Node
|
: public VisualNode
|
||||||
, public Singleton<DebugNode>
|
, public Singleton<DebugNode>
|
||||||
{
|
{
|
||||||
E2D_DECLARE_SINGLETON(DebugNode);
|
E2D_DECLARE_SINGLETON(DebugNode);
|
||||||
|
|
@ -36,6 +36,12 @@ namespace easy2d
|
||||||
|
|
||||||
virtual ~DebugNode();
|
virtual ~DebugNode();
|
||||||
|
|
||||||
|
// 显示调试信息
|
||||||
|
void Show();
|
||||||
|
|
||||||
|
// 隐藏调试信息
|
||||||
|
void Hide();
|
||||||
|
|
||||||
void AddDebugText(String const& text);
|
void AddDebugText(String const& text);
|
||||||
|
|
||||||
void ClearDebugText();
|
void ClearDebugText();
|
||||||
|
|
@ -44,6 +50,8 @@ namespace easy2d
|
||||||
|
|
||||||
void OnUpdate(Duration dt) override;
|
void OnUpdate(Duration dt) override;
|
||||||
|
|
||||||
|
static bool IsShown();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TextPtr debug_text_;
|
TextPtr debug_text_;
|
||||||
Array<TimePoint> frame_time_;
|
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.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
#include "Geometry.h"
|
#include "Geometry.h"
|
||||||
#include "Factory.h"
|
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
|
|
||||||
|
|
@ -99,7 +98,7 @@ namespace easy2d
|
||||||
BOOL ret = 0;
|
BOOL ret = 0;
|
||||||
// no matter it failed or not
|
// no matter it failed or not
|
||||||
geo_->FillContainsPoint(
|
geo_->FillContainsPoint(
|
||||||
ToD2dPoint2F(point),
|
DX::ConvertToPoint2F(point),
|
||||||
D2D1::Matrix3x2F::Identity(),
|
D2D1::Matrix3x2F::Identity(),
|
||||||
&ret
|
&ret
|
||||||
);
|
);
|
||||||
|
|
@ -126,10 +125,10 @@ namespace easy2d
|
||||||
|
|
||||||
void LineGeometry::SetLine(Point const & begin, Point const & end)
|
void LineGeometry::SetLine(Point const & begin, Point const & end)
|
||||||
{
|
{
|
||||||
D2DPathGeometryPtr path_geo;
|
ComPtr<ID2D1PathGeometry> path_geo;
|
||||||
D2DGeometrySinkPtr path_sink;
|
ComPtr<ID2D1GeometrySink> path_sink;
|
||||||
|
|
||||||
HRESULT hr = Factory::Instance().CreatePathGeometry(path_geo);
|
HRESULT hr = Renderer::Instance().GetDeviceResources()->GetD2DFactory()->CreatePathGeometry(&path_geo);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
|
@ -138,8 +137,8 @@ namespace easy2d
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
path_sink->BeginFigure(ToD2dPoint2F(begin), D2D1_FIGURE_BEGIN_FILLED);
|
path_sink->BeginFigure(DX::ConvertToPoint2F(begin), D2D1_FIGURE_BEGIN_FILLED);
|
||||||
path_sink->AddLine(ToD2dPoint2F(end));
|
path_sink->AddLine(DX::ConvertToPoint2F(end));
|
||||||
path_sink->EndFigure(D2D1_FIGURE_END_OPEN);
|
path_sink->EndFigure(D2D1_FIGURE_END_OPEN);
|
||||||
hr = path_sink->Close();
|
hr = path_sink->Close();
|
||||||
}
|
}
|
||||||
|
|
@ -185,8 +184,10 @@ namespace easy2d
|
||||||
|
|
||||||
void RectangleGeometry::SetRect(Rect const & rect)
|
void RectangleGeometry::SetRect(Rect const & rect)
|
||||||
{
|
{
|
||||||
D2DRectangleGeometryPtr geo;
|
ComPtr<ID2D1RectangleGeometry> geo;
|
||||||
if (SUCCEEDED(Factory::Instance().CreateRectangleGeometry(geo, rect)))
|
auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory();
|
||||||
|
|
||||||
|
if (SUCCEEDED(factory->CreateRectangleGeometry(DX::ConvertToRectF(rect), &geo)))
|
||||||
{
|
{
|
||||||
geo_ = geo;
|
geo_ = geo;
|
||||||
rect_ = rect;
|
rect_ = rect;
|
||||||
|
|
@ -224,8 +225,15 @@ namespace easy2d
|
||||||
|
|
||||||
void CircleGeometry::SetCircle(Point const & center, float radius)
|
void CircleGeometry::SetCircle(Point const & center, float radius)
|
||||||
{
|
{
|
||||||
D2DEllipseGeometryPtr geo;
|
ComPtr<ID2D1EllipseGeometry> geo;
|
||||||
if (SUCCEEDED(Factory::Instance().CreateEllipseGeometry(geo, center, radius, radius)))
|
auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory();
|
||||||
|
|
||||||
|
if (SUCCEEDED(factory->CreateEllipseGeometry(
|
||||||
|
D2D1::Ellipse(
|
||||||
|
DX::ConvertToPoint2F(center),
|
||||||
|
radius,
|
||||||
|
radius),
|
||||||
|
&geo)))
|
||||||
{
|
{
|
||||||
geo_ = geo;
|
geo_ = geo;
|
||||||
center_ = center;
|
center_ = center;
|
||||||
|
|
@ -265,8 +273,15 @@ namespace easy2d
|
||||||
|
|
||||||
void EllipseGeometry::SetEllipse(Point const & center, float radius_x, float radius_y)
|
void EllipseGeometry::SetEllipse(Point const & center, float radius_x, float radius_y)
|
||||||
{
|
{
|
||||||
D2DEllipseGeometryPtr geo;
|
ComPtr<ID2D1EllipseGeometry> geo;
|
||||||
if (SUCCEEDED(Factory::Instance().CreateEllipseGeometry(geo, center, radius_x, radius_y)))
|
auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory();
|
||||||
|
|
||||||
|
if (SUCCEEDED(factory->CreateEllipseGeometry(
|
||||||
|
D2D1::Ellipse(
|
||||||
|
DX::ConvertToPoint2F(center),
|
||||||
|
radius_x,
|
||||||
|
radius_y),
|
||||||
|
&geo)))
|
||||||
{
|
{
|
||||||
geo_ = geo;
|
geo_ = geo;
|
||||||
radius_x_ = radius_x;
|
radius_x_ = radius_x;
|
||||||
|
|
@ -291,15 +306,17 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
current_geometry_ = nullptr;
|
current_geometry_ = nullptr;
|
||||||
|
|
||||||
|
auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory();
|
||||||
|
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
Factory::Instance().CreatePathGeometry(current_geometry_)
|
factory->CreatePathGeometry(¤t_geometry_)
|
||||||
);
|
);
|
||||||
|
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
current_geometry_->Open(¤t_sink_)
|
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)
|
void PathGeometry::EndPath(bool closed)
|
||||||
|
|
@ -321,7 +338,7 @@ namespace easy2d
|
||||||
void PathGeometry::AddLine(Point const & point)
|
void PathGeometry::AddLine(Point const & point)
|
||||||
{
|
{
|
||||||
if (current_sink_)
|
if (current_sink_)
|
||||||
current_sink_->AddLine(ToD2dPoint2F(point));
|
current_sink_->AddLine(DX::ConvertToPoint2F(point));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathGeometry::AddLines(Array<Point> const& points)
|
void PathGeometry::AddLines(Array<Point> const& points)
|
||||||
|
|
@ -341,9 +358,9 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
current_sink_->AddBezier(
|
current_sink_->AddBezier(
|
||||||
D2D1::BezierSegment(
|
D2D1::BezierSegment(
|
||||||
ToD2dPoint2F(point1),
|
DX::ConvertToPoint2F(point1),
|
||||||
ToD2dPoint2F(point2),
|
DX::ConvertToPoint2F(point2),
|
||||||
ToD2dPoint2F(point3)
|
DX::ConvertToPoint2F(point3)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -355,8 +372,8 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
current_sink_->AddArc(
|
current_sink_->AddArc(
|
||||||
D2D1::ArcSegment(
|
D2D1::ArcSegment(
|
||||||
ToD2dPoint2F(point),
|
DX::ConvertToPoint2F(point),
|
||||||
ToD2dSizeF(radius),
|
DX::ConvertToSizeF(radius),
|
||||||
rotation,
|
rotation,
|
||||||
clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,
|
clockwise ? D2D1_SWEEP_DIRECTION_CLOCKWISE : D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE,
|
||||||
is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE
|
is_small ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE
|
||||||
|
|
@ -404,8 +421,16 @@ namespace easy2d
|
||||||
|
|
||||||
void RoundedRectGeometry::SetRoundedRect(Rect const & rect, float radius_x, float radius_y)
|
void RoundedRectGeometry::SetRoundedRect(Rect const & rect, float radius_x, float radius_y)
|
||||||
{
|
{
|
||||||
D2DRoundedRectangleGeometryPtr geo;
|
ComPtr<ID2D1RoundedRectangleGeometry> geo;
|
||||||
if (SUCCEEDED(Factory::Instance().CreateRoundedRectangleGeometry(geo, rect, radius_x, radius_y)))
|
auto factory = Renderer::Instance().GetDeviceResources()->GetD2DFactory();
|
||||||
|
|
||||||
|
if (SUCCEEDED(factory->CreateRoundedRectangleGeometry(
|
||||||
|
D2D1::RoundedRect(
|
||||||
|
DX::ConvertToRectF(rect),
|
||||||
|
radius_x,
|
||||||
|
radius_y
|
||||||
|
),
|
||||||
|
&geo)))
|
||||||
{
|
{
|
||||||
geo_ = geo;
|
geo_ = geo;
|
||||||
rect_ = rect;
|
rect_ = rect;
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ namespace easy2d
|
||||||
float ComputeArea();
|
float ComputeArea();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
D2DGeometryPtr geo_;
|
ComPtr<ID2D1Geometry> geo_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -254,8 +254,8 @@ namespace easy2d
|
||||||
void ClearPath();
|
void ClearPath();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
D2DPathGeometryPtr current_geometry_;
|
ComPtr<ID2D1PathGeometry> current_geometry_;
|
||||||
D2DGeometrySinkPtr current_sink_;
|
ComPtr<ID2D1GeometrySink> current_sink_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,14 +70,12 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
if (geometry_ && geometry_->geo_)
|
if (geometry_ && geometry_->geo_)
|
||||||
{
|
{
|
||||||
auto& rt = RenderSystem::Instance();
|
Renderer::Instance().FillGeometry(
|
||||||
|
geometry_->geo_.Get(),
|
||||||
rt.FillGeometry(
|
|
||||||
geometry_->geo_,
|
|
||||||
fill_color_
|
fill_color_
|
||||||
);
|
);
|
||||||
|
|
||||||
rt.DrawGeometry(
|
Renderer::Instance().DrawGeometry(
|
||||||
geometry_->geo_,
|
geometry_->geo_,
|
||||||
stroke_color_,
|
stroke_color_,
|
||||||
stroke_width_,
|
stroke_width_,
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
// 섯부暠近
|
// 섯부暠近
|
||||||
class E2D_API GeometryNode
|
class E2D_API GeometryNode
|
||||||
: public Node
|
: public VisualNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GeometryNode();
|
GeometryNode();
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
#include "render.h"
|
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
|
#include "render.h"
|
||||||
#include "../utils/File.h"
|
#include "../utils/File.h"
|
||||||
#include "../utils/string.h"
|
#include "../utils/string.h"
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ namespace easy2d
|
||||||
this->Crop(crop_rect);
|
this->Crop(crop_rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::Image(D2DBitmapPtr const & bitmap)
|
Image::Image(ComPtr<ID2D1Bitmap> const & bitmap)
|
||||||
: Image()
|
: Image()
|
||||||
{
|
{
|
||||||
SetBitmap(bitmap);
|
SetBitmap(bitmap);
|
||||||
|
|
@ -58,7 +58,7 @@ namespace easy2d
|
||||||
bool Image::Load(Resource const& res)
|
bool Image::Load(Resource const& res)
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
D2DBitmapPtr bitmap;
|
ComPtr<ID2D1Bitmap> bitmap;
|
||||||
|
|
||||||
if (res.IsFileType())
|
if (res.IsFileType())
|
||||||
{
|
{
|
||||||
|
|
@ -67,11 +67,11 @@ namespace easy2d
|
||||||
E2D_WARNING_LOG(L"Image file '%s' not found!", res.GetFileName().c_str());
|
E2D_WARNING_LOG(L"Image file '%s' not found!", res.GetFileName().c_str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
hr = RenderSystem::Instance().CreateBitmapFromFile(bitmap, res.GetFileName());
|
hr = Renderer::Instance().GetDeviceResources()->CreateBitmapFromFile(bitmap, res.GetFileName());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hr = RenderSystem::Instance().CreateBitmapFromResource(bitmap, res);
|
hr = Renderer::Instance().GetDeviceResources()->CreateBitmapFromResource(bitmap, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
|
@ -164,12 +164,12 @@ namespace easy2d
|
||||||
return crop_rect_;
|
return crop_rect_;
|
||||||
}
|
}
|
||||||
|
|
||||||
D2DBitmapPtr const& Image::GetBitmap() const
|
ComPtr<ID2D1Bitmap> const& Image::GetBitmap() const
|
||||||
{
|
{
|
||||||
return bitmap_;
|
return bitmap_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::SetBitmap(D2DBitmapPtr const & bitmap)
|
void Image::SetBitmap(ComPtr<ID2D1Bitmap> const & bitmap)
|
||||||
{
|
{
|
||||||
if (bitmap)
|
if (bitmap)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ namespace easy2d
|
||||||
);
|
);
|
||||||
|
|
||||||
explicit Image(
|
explicit Image(
|
||||||
D2DBitmapPtr const& bitmap
|
ComPtr<ID2D1Bitmap> const& bitmap
|
||||||
);
|
);
|
||||||
|
|
||||||
virtual ~Image();
|
virtual ~Image();
|
||||||
|
|
@ -89,15 +89,15 @@ namespace easy2d
|
||||||
// »ñÈ¡²Ã¼ô¾ØÐÎ
|
// »ñÈ¡²Ã¼ô¾ØÐÎ
|
||||||
Rect const& GetCropRect() const;
|
Rect const& GetCropRect() const;
|
||||||
|
|
||||||
D2DBitmapPtr const& GetBitmap() const;
|
ComPtr<ID2D1Bitmap> const& GetBitmap() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void SetBitmap(
|
void SetBitmap(
|
||||||
D2DBitmapPtr const& bitmap
|
ComPtr<ID2D1Bitmap> const& bitmap
|
||||||
);
|
);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Rect crop_rect_;
|
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;
|
hwnd_ = hwnd;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ namespace easy2d
|
||||||
// 資誼報炎恫炎
|
// 資誼報炎恫炎
|
||||||
Point GetMousePos();
|
Point GetMousePos();
|
||||||
|
|
||||||
HRESULT Init(HWND hwnd, bool debug);
|
HRESULT Init(HWND hwnd);
|
||||||
|
|
||||||
void Update();
|
void Update();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@
|
||||||
|
|
||||||
#include "Node.h"
|
#include "Node.h"
|
||||||
#include "Action.h"
|
#include "Action.h"
|
||||||
#include "Factory.h"
|
|
||||||
#include "Scene.h"
|
#include "Scene.h"
|
||||||
#include "Task.h"
|
#include "Task.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
|
|
@ -42,7 +41,7 @@ namespace easy2d
|
||||||
|
|
||||||
Node::Node()
|
Node::Node()
|
||||||
: visible_(true)
|
: visible_(true)
|
||||||
, pause_(false)
|
, update_pausing_(false)
|
||||||
, hover_(false)
|
, hover_(false)
|
||||||
, pressed_(false)
|
, pressed_(false)
|
||||||
, responsible_(false)
|
, responsible_(false)
|
||||||
|
|
@ -59,7 +58,7 @@ namespace easy2d
|
||||||
|
|
||||||
void Node::Update(Duration dt)
|
void Node::Update(Duration dt)
|
||||||
{
|
{
|
||||||
if (pause_)
|
if (update_pausing_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
UpdateActions(this, dt);
|
UpdateActions(this, dt);
|
||||||
|
|
@ -88,13 +87,9 @@ namespace easy2d
|
||||||
|
|
||||||
UpdateTransform();
|
UpdateTransform();
|
||||||
|
|
||||||
auto& rt = RenderSystem::Instance();
|
|
||||||
|
|
||||||
if (children_.IsEmpty())
|
if (children_.IsEmpty())
|
||||||
{
|
{
|
||||||
rt.SetTransform(transform_matrix_);
|
PrepareRender();
|
||||||
rt.SetOpacity(display_opacity_);
|
|
||||||
|
|
||||||
OnRender();
|
OnRender();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -110,9 +105,7 @@ namespace easy2d
|
||||||
child = child->NextItem().Get();
|
child = child->NextItem().Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
rt.SetTransform(transform_matrix_);
|
PrepareRender();
|
||||||
rt.SetOpacity(display_opacity_);
|
|
||||||
|
|
||||||
OnRender();
|
OnRender();
|
||||||
|
|
||||||
while (child)
|
while (child)
|
||||||
|
|
@ -184,16 +177,6 @@ namespace easy2d
|
||||||
EventDispatcher::Dispatch(evt);
|
EventDispatcher::Dispatch(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::PauseUpdating()
|
|
||||||
{
|
|
||||||
pause_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Node::ResumeUpdating()
|
|
||||||
{
|
|
||||||
pause_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Matrix const & Node::GetTransformMatrix() const
|
Matrix const & Node::GetTransformMatrix() const
|
||||||
{
|
{
|
||||||
UpdateTransform();
|
UpdateTransform();
|
||||||
|
|
@ -607,4 +590,12 @@ namespace easy2d
|
||||||
Point local = GetTransformInverseMatrix().Transform(point);
|
Point local = GetTransformInverseMatrix().Transform(point);
|
||||||
return GetBounds().ContainsPoint(local);
|
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 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; }
|
inline void SetCallbackOnUpdate(UpdateCallback const& cb) { cb_update_ = cb; }
|
||||||
|
|
@ -365,6 +365,8 @@ namespace easy2d
|
||||||
);
|
);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void PrepareRender() {}
|
||||||
|
|
||||||
void Update(Duration dt);
|
void Update(Duration dt);
|
||||||
|
|
||||||
void Render();
|
void Render();
|
||||||
|
|
@ -380,7 +382,7 @@ namespace easy2d
|
||||||
bool hover_;
|
bool hover_;
|
||||||
bool pressed_;
|
bool pressed_;
|
||||||
bool responsible_;
|
bool responsible_;
|
||||||
bool pause_;
|
bool update_pausing_;
|
||||||
int z_order_;
|
int z_order_;
|
||||||
float opacity_;
|
float opacity_;
|
||||||
float display_opacity_;
|
float display_opacity_;
|
||||||
|
|
@ -398,4 +400,13 @@ namespace easy2d
|
||||||
mutable Matrix transform_matrix_;
|
mutable Matrix transform_matrix_;
|
||||||
mutable Matrix transform_matrix_inverse_;
|
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
|
class E2D_API Scene
|
||||||
: public Node
|
: public VisualNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Scene();
|
Scene();
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
if (image_)
|
if (image_)
|
||||||
{
|
{
|
||||||
RenderSystem::Instance().DrawImage(image_, GetBounds());
|
Renderer::Instance().DrawImage(image_, GetBounds());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -26,7 +26,7 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
// ¾«Áé
|
// ¾«Áé
|
||||||
class E2D_API Sprite
|
class E2D_API Sprite
|
||||||
: public Node
|
: public VisualNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Sprite();
|
Sprite();
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,7 @@
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
#include "Text.h"
|
#include "Text.h"
|
||||||
#include "Factory.h"
|
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "include-forwards.h"
|
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
|
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
|
|
@ -45,6 +43,7 @@ namespace easy2d
|
||||||
Text::Text()
|
Text::Text()
|
||||||
: font_(text_default_font)
|
: font_(text_default_font)
|
||||||
, style_(text_default_style)
|
, style_(text_default_style)
|
||||||
|
, layout_dirty_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,8 +66,8 @@ namespace easy2d
|
||||||
: font_(font)
|
: font_(font)
|
||||||
, style_(style)
|
, style_(style)
|
||||||
, text_(text)
|
, text_(text)
|
||||||
|
, layout_dirty_(true)
|
||||||
{
|
{
|
||||||
UpdateLayout();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Text::~Text()
|
Text::~Text()
|
||||||
|
|
@ -127,6 +126,7 @@ namespace easy2d
|
||||||
|
|
||||||
int Text::GetLineCount()
|
int Text::GetLineCount()
|
||||||
{
|
{
|
||||||
|
UpdateLayout();
|
||||||
if (text_layout_)
|
if (text_layout_)
|
||||||
{
|
{
|
||||||
DWRITE_TEXT_METRICS metrics;
|
DWRITE_TEXT_METRICS metrics;
|
||||||
|
|
@ -138,6 +138,12 @@ namespace easy2d
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Size const& Text::GetLayoutSize() const
|
||||||
|
{
|
||||||
|
UpdateLayout();
|
||||||
|
return layout_size_;
|
||||||
|
}
|
||||||
|
|
||||||
bool Text::IsItalic() const
|
bool Text::IsItalic() const
|
||||||
{
|
{
|
||||||
return font_.italic;
|
return font_.italic;
|
||||||
|
|
@ -161,19 +167,19 @@ namespace easy2d
|
||||||
void Text::SetText(String const& text)
|
void Text::SetText(String const& text)
|
||||||
{
|
{
|
||||||
text_ = text;
|
text_ = text;
|
||||||
UpdateLayout();
|
layout_dirty_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Text::SetStyle(const TextStyle& style)
|
void Text::SetStyle(const TextStyle& style)
|
||||||
{
|
{
|
||||||
style_ = style;
|
style_ = style;
|
||||||
UpdateLayout();
|
layout_dirty_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Text::SetFont(const Font & font)
|
void Text::SetFont(const Font & font)
|
||||||
{
|
{
|
||||||
font_ = font;
|
font_ = font;
|
||||||
UpdateLayout();
|
layout_dirty_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Text::SetFontFamily(String const& family)
|
void Text::SetFontFamily(String const& family)
|
||||||
|
|
@ -181,7 +187,7 @@ namespace easy2d
|
||||||
if (font_.family != family)
|
if (font_.family != family)
|
||||||
{
|
{
|
||||||
font_.family = family;
|
font_.family = family;
|
||||||
UpdateLayout();
|
layout_dirty_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,7 +196,7 @@ namespace easy2d
|
||||||
if (font_.size != size)
|
if (font_.size != size)
|
||||||
{
|
{
|
||||||
font_.size = size;
|
font_.size = size;
|
||||||
UpdateLayout();
|
layout_dirty_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,7 +205,7 @@ namespace easy2d
|
||||||
if (font_.weight != weight)
|
if (font_.weight != weight)
|
||||||
{
|
{
|
||||||
font_.weight = weight;
|
font_.weight = weight;
|
||||||
UpdateLayout();
|
layout_dirty_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -213,7 +219,7 @@ namespace easy2d
|
||||||
if (font_.italic != val)
|
if (font_.italic != val)
|
||||||
{
|
{
|
||||||
font_.italic = val;
|
font_.italic = val;
|
||||||
UpdateLayout();
|
layout_dirty_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,7 +228,7 @@ namespace easy2d
|
||||||
if (style_.wrap != wrap)
|
if (style_.wrap != wrap)
|
||||||
{
|
{
|
||||||
style_.wrap = wrap;
|
style_.wrap = wrap;
|
||||||
UpdateLayout();
|
layout_dirty_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -231,7 +237,7 @@ namespace easy2d
|
||||||
if (style_.wrap_width != wrap_width)
|
if (style_.wrap_width != wrap_width)
|
||||||
{
|
{
|
||||||
style_.wrap_width = std::max(wrap_width, 0.f);
|
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)
|
if (style_.line_spacing != line_spacing)
|
||||||
{
|
{
|
||||||
style_.line_spacing = line_spacing;
|
style_.line_spacing = line_spacing;
|
||||||
UpdateLayout();
|
layout_dirty_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -249,7 +255,7 @@ namespace easy2d
|
||||||
if (style_.alignment != align)
|
if (style_.alignment != align)
|
||||||
{
|
{
|
||||||
style_.alignment = align;
|
style_.alignment = align;
|
||||||
UpdateLayout();
|
layout_dirty_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -258,7 +264,7 @@ namespace easy2d
|
||||||
if (style_.underline != underline)
|
if (style_.underline != underline)
|
||||||
{
|
{
|
||||||
style_.underline = underline;
|
style_.underline = underline;
|
||||||
UpdateLayout();
|
layout_dirty_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -267,7 +273,7 @@ namespace easy2d
|
||||||
if (style_.strikethrough != strikethrough)
|
if (style_.strikethrough != strikethrough)
|
||||||
{
|
{
|
||||||
style_.strikethrough = strikethrough;
|
style_.strikethrough = strikethrough;
|
||||||
UpdateLayout();
|
layout_dirty_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -293,22 +299,27 @@ namespace easy2d
|
||||||
|
|
||||||
void Text::OnRender()
|
void Text::OnRender()
|
||||||
{
|
{
|
||||||
|
UpdateLayout();
|
||||||
|
|
||||||
if (text_layout_)
|
if (text_layout_)
|
||||||
{
|
{
|
||||||
auto& rt = RenderSystem::Instance();
|
Renderer::Instance().SetTextStyle(
|
||||||
rt.SetTextStyle(
|
|
||||||
style_.color,
|
style_.color,
|
||||||
style_.outline,
|
style_.outline,
|
||||||
style_.outline_color,
|
style_.outline_color,
|
||||||
style_.outline_width,
|
style_.outline_width,
|
||||||
style_.outline_stroke
|
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_format_ = nullptr;
|
||||||
text_layout_ = nullptr;
|
text_layout_ = nullptr;
|
||||||
|
|
||||||
|
|
@ -316,24 +327,21 @@ namespace easy2d
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
Factory::Instance().CreateTextFormat(
|
Renderer::Instance().GetDeviceResources()->CreateTextFormat(
|
||||||
text_format_,
|
text_format_,
|
||||||
font_,
|
font_,
|
||||||
style_
|
style_
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
Size layout_size;
|
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
Factory::Instance().CreateTextLayout(
|
Renderer::Instance().GetDeviceResources()->CreateTextLayout(
|
||||||
text_layout_,
|
text_layout_,
|
||||||
layout_size,
|
layout_size_,
|
||||||
text_,
|
text_,
|
||||||
text_format_,
|
text_format_,
|
||||||
style_
|
style_
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
this->SetSize(layout_size);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
// 文本
|
// 文本
|
||||||
class E2D_API Text
|
class E2D_API Text
|
||||||
: public Node
|
: public VisualNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Text();
|
Text();
|
||||||
|
|
@ -87,6 +87,9 @@ namespace easy2d
|
||||||
// 获取文本显示行数
|
// 获取文本显示行数
|
||||||
int GetLineCount();
|
int GetLineCount();
|
||||||
|
|
||||||
|
// 获取文字布局大小
|
||||||
|
Size const& GetLayoutSize() const;
|
||||||
|
|
||||||
// 是否是斜体
|
// 是否是斜体
|
||||||
bool IsItalic() const;
|
bool IsItalic() const;
|
||||||
|
|
||||||
|
|
@ -202,13 +205,16 @@ namespace easy2d
|
||||||
void OnRender() override;
|
void OnRender() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void UpdateLayout();
|
void UpdateLayout() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
String text_;
|
String text_;
|
||||||
Font font_;
|
Font font_;
|
||||||
TextStyle style_;
|
TextStyle style_;
|
||||||
D2DTextFormatPtr text_format_;
|
|
||||||
D2DTextLayoutPtr text_layout_;
|
mutable bool layout_dirty_;
|
||||||
|
mutable Size layout_size_;
|
||||||
|
mutable ComPtr<IDWriteTextFormat> text_format_;
|
||||||
|
mutable ComPtr<IDWriteTextLayout> text_layout_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -19,11 +19,11 @@
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "helper.hpp"
|
#include "../math/Matrix.hpp"
|
||||||
|
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
{
|
{
|
||||||
class E2D_API Transform
|
class Transform
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
float rotation; // Ðýת
|
float rotation; // Ðýת
|
||||||
|
|
|
||||||
|
|
@ -66,14 +66,14 @@ namespace easy2d
|
||||||
if (in_scene_)
|
if (in_scene_)
|
||||||
{
|
{
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
RenderSystem::Instance().CreateLayer(in_layer_)
|
Renderer::Instance().CreateLayer(in_layer_)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out_scene_)
|
if (out_scene_)
|
||||||
{
|
{
|
||||||
ThrowIfFailed(
|
ThrowIfFailed(
|
||||||
RenderSystem::Instance().CreateLayer(out_layer_)
|
Renderer::Instance().CreateLayer(out_layer_)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -101,34 +101,34 @@ namespace easy2d
|
||||||
|
|
||||||
void Transition::Render()
|
void Transition::Render()
|
||||||
{
|
{
|
||||||
auto& rt = RenderSystem::Instance();
|
auto& renderer = Renderer::Instance();
|
||||||
|
|
||||||
if (out_scene_)
|
if (out_scene_)
|
||||||
{
|
{
|
||||||
rt.PushClip(
|
renderer.PushClip(
|
||||||
out_scene_->GetTransformMatrix(),
|
out_scene_->GetTransformMatrix(),
|
||||||
window_size_
|
window_size_
|
||||||
);
|
);
|
||||||
rt.PushLayer(out_layer_, out_layer_prop_);
|
renderer.PushLayer(out_layer_, out_layer_prop_);
|
||||||
|
|
||||||
out_scene_->Render();
|
out_scene_->Render();
|
||||||
|
|
||||||
rt.PopLayer();
|
renderer.PopLayer();
|
||||||
rt.PopClip();
|
renderer.PopClip();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_scene_)
|
if (in_scene_)
|
||||||
{
|
{
|
||||||
rt.PushClip(
|
renderer.PushClip(
|
||||||
in_scene_->GetTransformMatrix(),
|
in_scene_->GetTransformMatrix(),
|
||||||
window_size_
|
window_size_
|
||||||
);
|
);
|
||||||
rt.PushLayer(in_layer_, in_layer_prop_);
|
renderer.PushLayer(in_layer_, in_layer_prop_);
|
||||||
|
|
||||||
in_scene_->Render();
|
in_scene_->Render();
|
||||||
|
|
||||||
rt.PopLayer();
|
renderer.PopLayer();
|
||||||
rt.PopClip();
|
renderer.PopClip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,8 @@ namespace easy2d
|
||||||
Size window_size_;
|
Size window_size_;
|
||||||
ScenePtr out_scene_;
|
ScenePtr out_scene_;
|
||||||
ScenePtr in_scene_;
|
ScenePtr in_scene_;
|
||||||
D2DLayerPtr out_layer_;
|
ComPtr<ID2D1Layer> out_layer_;
|
||||||
D2DLayerPtr in_layer_;
|
ComPtr<ID2D1Layer> in_layer_;
|
||||||
LayerProperties out_layer_prop_;
|
LayerProperties out_layer_prop_;
|
||||||
LayerProperties in_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");
|
E2D_LOG(L"Initing audio resources");
|
||||||
|
|
||||||
HRESULT hr = modules::MediaFoundation::Get().MFStartup(MF_VERSION, MFSTARTUP_FULL);
|
HRESULT hr = modules::MediaFoundation::Get().MFStartup(MF_VERSION, MFSTARTUP_FULL);
|
||||||
|
|
@ -202,7 +200,7 @@ namespace easy2d
|
||||||
mastering_voice_ = nullptr;
|
mastering_voice_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SafeRelease(x_audio2_);
|
DX::SafeRelease(x_audio2_);
|
||||||
|
|
||||||
modules::MediaFoundation::Get().MFShutdown();
|
modules::MediaFoundation::Get().MFShutdown();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ namespace easy2d
|
||||||
using VoiceMap = UnorderedSet<Voice*>;
|
using VoiceMap = UnorderedSet<Voice*>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HRESULT Init(bool debug);
|
HRESULT Init();
|
||||||
|
|
||||||
void Destroy();
|
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 "closure.hpp"
|
||||||
#include "../math/vector.hpp"
|
#include "../math/vector.hpp"
|
||||||
#include "../math/Rect.hpp"
|
#include "../math/Rect.hpp"
|
||||||
#include "../math/Matrix.h"
|
#include "../math/Matrix.hpp"
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
@ -72,8 +72,6 @@ namespace easy2d
|
||||||
|
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
{
|
{
|
||||||
// "Ptr" is a shorthand for "Smart Pointer"
|
|
||||||
|
|
||||||
E2D_DECLARE_SMART_PTR(Object);
|
E2D_DECLARE_SMART_PTR(Object);
|
||||||
E2D_DECLARE_SMART_PTR(Image);
|
E2D_DECLARE_SMART_PTR(Image);
|
||||||
E2D_DECLARE_SMART_PTR(Music);
|
E2D_DECLARE_SMART_PTR(Music);
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
#include "Color.h"
|
#include "Color.h"
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "helper.hpp"
|
#include "helper.hpp"
|
||||||
#include "d2dhelper.hpp"
|
#include "../DX/helper.hpp"
|
||||||
|
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,10 @@ namespace easy2d
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
{
|
||||||
E2D_ERROR_LOG(L"Fatal error with HRESULT of %08X", 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");
|
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()
|
XAudio2::XAudio2()
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
#include <mfapi.h>
|
#include <mfapi.h>
|
||||||
#include <mfidl.h>
|
#include <mfidl.h>
|
||||||
#include <mfreadwrite.h>
|
#include <mfreadwrite.h>
|
||||||
|
#include <d3d11.h>
|
||||||
|
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
{
|
{
|
||||||
|
|
@ -57,6 +58,7 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
DirectX();
|
DirectX();
|
||||||
|
|
||||||
|
HMODULE d3d11;
|
||||||
HMODULE d2d;
|
HMODULE d2d;
|
||||||
HMODULE dwrite;
|
HMODULE dwrite;
|
||||||
|
|
||||||
|
|
@ -73,6 +75,7 @@ namespace easy2d
|
||||||
|
|
||||||
PFN_D2D1CreateFactory D2D1CreateFactory;
|
PFN_D2D1CreateFactory D2D1CreateFactory;
|
||||||
PFN_DWriteCreateFactory DWriteCreateFactory;
|
PFN_DWriteCreateFactory DWriteCreateFactory;
|
||||||
|
PFN_D3D11_CREATE_DEVICE D3D11CreateDevice;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,220 +20,233 @@
|
||||||
|
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
#include "Factory.h"
|
#include "render.h"
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
#include "Transform.hpp"
|
#include "Transform.hpp"
|
||||||
|
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
{
|
{
|
||||||
RenderSystem::RenderSystem()
|
Renderer::Renderer()
|
||||||
: fps_text_format_(nullptr)
|
: antialias_(true)
|
||||||
, fps_text_layout_(nullptr)
|
, text_antialias_(TextAntialias::ClearType)
|
||||||
, clear_color_(D2D1::ColorF(D2D1::ColorF::Black))
|
, clear_color_(D2D1::ColorF(D2D1::ColorF::Black))
|
||||||
, opacity_(1.f)
|
, opacity_(1.f)
|
||||||
, debug_(false)
|
{
|
||||||
, window_occluded_(false)
|
status_.primitives = 0;
|
||||||
, vsync_enabled_(true)
|
}
|
||||||
, antialias_(true)
|
|
||||||
, text_antialias_(TextAntialias::ClearType)
|
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");
|
E2D_LOG(L"Destroying device resources");
|
||||||
|
|
||||||
vsync_enabled_ = vsync;
|
|
||||||
debug_ = debug;
|
|
||||||
|
|
||||||
return CreateResources(hwnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderSystem::Destroy()
|
|
||||||
{
|
|
||||||
E2D_LOG(L"Destroying graphics resources");
|
|
||||||
|
|
||||||
ClearImageCache();
|
|
||||||
|
|
||||||
|
device_resources_.Reset();
|
||||||
|
factory_.Reset();
|
||||||
|
device_context_.Reset();
|
||||||
|
drawing_state_block_.Reset();
|
||||||
text_renderer_.Reset();
|
text_renderer_.Reset();
|
||||||
solid_brush_.Reset();
|
solid_color_brush_.Reset();
|
||||||
render_target_.Reset();
|
|
||||||
fps_text_format_.Reset();
|
|
||||||
fps_text_layout_.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_.start = time::Now();
|
||||||
status_.primitives = 0;
|
status_.primitives = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
device_context_->SaveDrawingState(drawing_state_block_.Get());
|
||||||
{
|
|
||||||
window_occluded_ = !!(render_target_->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED);
|
|
||||||
|
|
||||||
if (!window_occluded_)
|
device_context_->BeginDraw();
|
||||||
{
|
device_context_->Clear(clear_color_);
|
||||||
render_target_->BeginDraw();
|
return S_OK;
|
||||||
render_target_->Clear(clear_color_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT RenderSystem::EndDraw()
|
HRESULT Renderer::EndDraw()
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
if (!device_context_)
|
||||||
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
if (!window_occluded_)
|
HRESULT hr = device_context_->EndDraw();
|
||||||
|
|
||||||
|
device_context_->RestoreDrawingState(drawing_state_block_.Get());
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
hr = render_target_->EndDraw();
|
// The first argument instructs DXGI to block until VSync.
|
||||||
|
hr = device_resources_->GetDXGISwapChain()->Present(1, 0);
|
||||||
if (hr == D2DERR_RECREATE_TARGET)
|
|
||||||
{
|
|
||||||
// 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源
|
|
||||||
// 并在下一次调用时重建资源
|
|
||||||
DiscardResources();
|
|
||||||
hr = S_OK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug_)
|
if (hr == DXGI_ERROR_DEVICE_REMOVED || hr == DXGI_ERROR_DEVICE_RESET)
|
||||||
|
{
|
||||||
|
// 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源
|
||||||
|
hr = HandleDeviceLost();
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (debug_)
|
||||||
{
|
{
|
||||||
status_.duration = time::Now() - status_.start;
|
status_.duration = time::Now() - status_.start;
|
||||||
}
|
}
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderSystem::ClearImageCache()
|
HRESULT Renderer::CreateLayer(ComPtr<ID2D1Layer>& layer)
|
||||||
{
|
{
|
||||||
bitmap_cache_.clear();
|
if (!device_context_)
|
||||||
}
|
|
||||||
|
|
||||||
D2DHwndRenderTargetPtr const & RenderSystem::GetRenderTarget() const
|
|
||||||
{
|
|
||||||
return render_target_;
|
|
||||||
}
|
|
||||||
|
|
||||||
D2DSolidColorBrushPtr const & RenderSystem::GetSolidBrush() const
|
|
||||||
{
|
|
||||||
return solid_brush_;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT RenderSystem::CreateLayer(D2DLayerPtr& layer)
|
|
||||||
{
|
|
||||||
if (!render_target_)
|
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
layer = nullptr;
|
layer = nullptr;
|
||||||
return render_target_->CreateLayer(&layer);
|
return device_context_->CreateLayer(&layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT RenderSystem::CreateSolidColorBrush(D2DSolidColorBrushPtr & brush) const
|
HRESULT Renderer::DrawGeometry(
|
||||||
{
|
ComPtr<ID2D1Geometry> const& geometry,
|
||||||
if (!render_target_)
|
|
||||||
return E_UNEXPECTED;
|
|
||||||
|
|
||||||
brush = nullptr;
|
|
||||||
return render_target_->CreateSolidColorBrush(
|
|
||||||
D2D1::ColorF(D2D1::ColorF::White),
|
|
||||||
&brush
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT RenderSystem::DrawGeometry(
|
|
||||||
D2DGeometryPtr const& geometry,
|
|
||||||
Color const& stroke_color,
|
Color const& stroke_color,
|
||||||
float stroke_width,
|
float stroke_width,
|
||||||
StrokeStyle stroke
|
StrokeStyle stroke
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!solid_brush_ ||
|
if (!solid_color_brush_ || !device_context_)
|
||||||
!render_target_)
|
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
if (window_occluded_)
|
solid_color_brush_->SetColor(DX::ConvertToColorF(stroke_color));
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
solid_brush_->SetColor(ToD2dColorF(stroke_color));
|
device_context_->DrawGeometry(
|
||||||
auto stroke_style = Factory::Instance().GetStrokeStyle(stroke);
|
|
||||||
render_target_->DrawGeometry(
|
|
||||||
geometry.Get(),
|
geometry.Get(),
|
||||||
solid_brush_.Get(),
|
solid_color_brush_.Get(),
|
||||||
stroke_width,
|
stroke_width,
|
||||||
stroke_style.Get()
|
device_resources_->GetStrokeStyle(stroke)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (debug_)
|
// if (debug_)
|
||||||
++status_.primitives;
|
++status_.primitives;
|
||||||
return S_OK;
|
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_ ||
|
if (!solid_color_brush_ || !device_context_)
|
||||||
!render_target_)
|
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
if (window_occluded_)
|
solid_color_brush_->SetColor(DX::ConvertToColorF(fill_color));
|
||||||
return S_OK;
|
device_context_->FillGeometry(
|
||||||
|
|
||||||
solid_brush_->SetColor(ToD2dColorF(fill_color));
|
|
||||||
render_target_->FillGeometry(
|
|
||||||
geometry.Get(),
|
geometry.Get(),
|
||||||
solid_brush_.Get()
|
solid_color_brush_.Get()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (debug_)
|
|
||||||
++status_.primitives;
|
|
||||||
return S_OK;
|
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;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
if (!image->GetBitmap())
|
if (!image->GetBitmap())
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
if (window_occluded_)
|
device_context_->DrawBitmap(
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
render_target_->DrawBitmap(
|
|
||||||
image->GetBitmap().Get(),
|
image->GetBitmap().Get(),
|
||||||
ToD2dRectF(dest_rect),
|
DX::ConvertToRectF(dest_rect),
|
||||||
opacity_,
|
opacity_,
|
||||||
D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
|
D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
|
||||||
ToD2dRectF(image->GetCropRect())
|
DX::ConvertToRectF(image->GetCropRect())
|
||||||
);
|
);
|
||||||
|
|
||||||
if (debug_)
|
// if (debug_)
|
||||||
++status_.primitives;
|
++status_.primitives;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT RenderSystem::DrawBitmap(
|
HRESULT Renderer::DrawBitmap(ComPtr<ID2D1Bitmap> const & bitmap)
|
||||||
D2DBitmapPtr const& bitmap
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (!render_target_)
|
if (!device_context_)
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
if (window_occluded_)
|
if (!bitmap)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
// Do not crop bitmap
|
// Do not crop bitmap
|
||||||
auto rect = D2D1::RectF(0.f, 0.f, bitmap->GetSize().width, bitmap->GetSize().height);
|
D2D_RECT_F rect = D2D1::RectF(0.f, 0.f, bitmap->GetSize().width, bitmap->GetSize().height);
|
||||||
render_target_->DrawBitmap(
|
device_context_->DrawBitmap(
|
||||||
bitmap.Get(),
|
bitmap.Get(),
|
||||||
rect,
|
rect,
|
||||||
opacity_,
|
opacity_,
|
||||||
|
|
@ -241,69 +254,56 @@ namespace easy2d
|
||||||
rect
|
rect
|
||||||
);
|
);
|
||||||
|
|
||||||
if (debug_)
|
// if (debug_)
|
||||||
++status_.primitives;
|
++status_.primitives;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT RenderSystem::DrawTextLayout(D2DTextLayoutPtr const& text_layout)
|
HRESULT Renderer::DrawTextLayout(ComPtr<IDWriteTextLayout> const& text_layout)
|
||||||
{
|
{
|
||||||
if (!text_renderer_)
|
if (!text_renderer_)
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
if (window_occluded_)
|
// if (debug_)
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
if (debug_)
|
|
||||||
++status_.primitives;
|
++status_.primitives;
|
||||||
return text_layout->Draw(nullptr, text_renderer_.Get(), 0, 0);
|
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;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
if (window_occluded_)
|
device_context_->SetTransform(DX::ConvertToMatrix3x2F(clip_matrix));
|
||||||
return S_OK;
|
device_context_->PushAxisAlignedClip(
|
||||||
|
|
||||||
render_target_->SetTransform(clip_matrix);
|
|
||||||
render_target_->PushAxisAlignedClip(
|
|
||||||
D2D1::RectF(0, 0, clip_size.x, clip_size.y),
|
D2D1::RectF(0, 0, clip_size.x, clip_size.y),
|
||||||
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
|
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE
|
||||||
);
|
);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT RenderSystem::PopClip()
|
HRESULT Renderer::PopClip()
|
||||||
{
|
{
|
||||||
if (!render_target_)
|
if (!device_context_)
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
if (window_occluded_)
|
device_context_->PopAxisAlignedClip();
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
render_target_->PopAxisAlignedClip();
|
|
||||||
return S_OK;
|
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_ ||
|
if (!device_context_ || !solid_color_brush_)
|
||||||
!solid_brush_)
|
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
if (window_occluded_)
|
device_context_->PushLayer(
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
render_target_->PushLayer(
|
|
||||||
D2D1::LayerParameters(
|
D2D1::LayerParameters(
|
||||||
ToD2dRectF(properties.area),
|
DX::ConvertToRectF(properties.area),
|
||||||
nullptr,
|
nullptr,
|
||||||
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
|
D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
|
||||||
D2D1::Matrix3x2F::Identity(),
|
D2D1::Matrix3x2F::Identity(),
|
||||||
properties.opacity,
|
properties.opacity,
|
||||||
solid_brush_.Get(),
|
solid_color_brush_.Get(),
|
||||||
D2D1_LAYER_OPTIONS_NONE
|
D2D1_LAYER_OPTIONS_NONE
|
||||||
),
|
),
|
||||||
layer.Get()
|
layer.Get()
|
||||||
|
|
@ -311,124 +311,39 @@ namespace easy2d
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT RenderSystem::PopLayer()
|
HRESULT Renderer::PopLayer()
|
||||||
{
|
{
|
||||||
if (!render_target_)
|
if (!device_context_)
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
if (window_occluded_)
|
device_context_->PopLayer();
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
render_target_->PopLayer();
|
|
||||||
return S_OK;
|
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;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
auto rtsize = render_target_->GetSize();
|
device_context_->SetTransform(DX::ConvertToMatrix3x2F(matrix));
|
||||||
size.x = rtsize.width;
|
|
||||||
size.y = rtsize.height;
|
|
||||||
return S_OK;
|
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)
|
HRESULT Renderer::SetTextStyle(
|
||||||
{
|
|
||||||
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(
|
|
||||||
Color const& color,
|
Color const& color,
|
||||||
bool has_outline,
|
bool has_outline,
|
||||||
Color const& outline_color,
|
Color const& outline_color,
|
||||||
|
|
@ -436,40 +351,34 @@ namespace easy2d
|
||||||
StrokeStyle outline_stroke
|
StrokeStyle outline_stroke
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!text_renderer_)
|
if (!text_renderer_ || !device_resources_)
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
auto stroke_style = Factory::Instance().GetStrokeStyle(outline_stroke);
|
|
||||||
text_renderer_->SetTextStyle(
|
text_renderer_->SetTextStyle(
|
||||||
ToD2dColorF(color),
|
DX::ConvertToColorF(color),
|
||||||
has_outline,
|
has_outline,
|
||||||
ToD2dColorF(outline_color),
|
DX::ConvertToColorF(outline_color),
|
||||||
outline_width,
|
outline_width,
|
||||||
stroke_style.Get()
|
device_resources_->GetStrokeStyle(outline_stroke)
|
||||||
);
|
);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderSystem::SetClearColor(const Color& color)
|
HRESULT Renderer::SetAntialiasMode(bool enabled)
|
||||||
{
|
{
|
||||||
clear_color_ = ToD2dColorF(color);
|
if (!device_context_)
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT RenderSystem::SetAntialiasMode(bool enabled)
|
|
||||||
{
|
|
||||||
if (!render_target_)
|
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
render_target_->SetAntialiasMode(
|
device_context_->SetAntialiasMode(
|
||||||
enabled ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED
|
enabled ? D2D1_ANTIALIAS_MODE_PER_PRIMITIVE : D2D1_ANTIALIAS_MODE_ALIASED
|
||||||
);
|
);
|
||||||
antialias_ = enabled;
|
antialias_ = enabled;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT RenderSystem::SetTextAntialiasMode(TextAntialias mode)
|
HRESULT Renderer::SetTextAntialiasMode(TextAntialias mode)
|
||||||
{
|
{
|
||||||
if (!render_target_)
|
if (!device_context_)
|
||||||
return E_UNEXPECTED;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
text_antialias_ = mode;
|
text_antialias_ = mode;
|
||||||
|
|
@ -491,78 +400,8 @@ namespace easy2d
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
render_target_->SetTextAntialiasMode(antialias_mode);
|
device_context_->SetTextAntialiasMode(antialias_mode);
|
||||||
return S_OK;
|
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
|
#pragma once
|
||||||
#include "include-forwards.h"
|
#include "include-forwards.h"
|
||||||
#include "time.h"
|
|
||||||
#include "Font.hpp"
|
#include "Font.hpp"
|
||||||
#include "Resource.h"
|
#include "Resource.h"
|
||||||
#include "TextRenderer.h"
|
|
||||||
#include "TextStyle.hpp"
|
#include "TextStyle.hpp"
|
||||||
#include "Singleton.hpp"
|
#include "Singleton.hpp"
|
||||||
#include "../math/Matrix.h"
|
#include "../DX/helper.hpp"
|
||||||
#include <unordered_map>
|
#include "../DX/DeviceResources.h"
|
||||||
|
#include "../DX/TextRenderer.h"
|
||||||
|
#include "time.h"
|
||||||
|
#include <d2d1.h>
|
||||||
|
#include <d2d1_1.h>
|
||||||
|
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
{
|
{
|
||||||
class E2D_API RenderSystem
|
struct RenderStatus
|
||||||
: public Singleton<RenderSystem>
|
|
||||||
{
|
{
|
||||||
E2D_DECLARE_SINGLETON(RenderSystem);
|
TimePoint start;
|
||||||
|
Duration duration;
|
||||||
|
int primitives;
|
||||||
|
};
|
||||||
|
|
||||||
struct Status
|
class E2D_API Renderer
|
||||||
{
|
: public Singleton<Renderer>
|
||||||
TimePoint start;
|
{
|
||||||
Duration duration;
|
E2D_DECLARE_SINGLETON(Renderer);
|
||||||
int primitives;
|
|
||||||
};
|
|
||||||
|
|
||||||
using BitmapMap = UnorderedMap<size_t, D2DBitmapPtr>;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
HRESULT Init(HWND hwnd, bool vsync, bool debug);
|
HRESULT Init(HWND hwnd);
|
||||||
|
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
// 开始渲染
|
inline RenderStatus const& GetStatus() const { return status_; }
|
||||||
HRESULT BeginDraw(HWND hwnd);
|
|
||||||
|
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 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(
|
void SetClearColor(
|
||||||
const Color& color
|
Color const& clear_color
|
||||||
);
|
);
|
||||||
|
|
||||||
// ÉèÖÿ¹¾â³Ýģʽ
|
// ÉèÖÿ¹¾â³Ýģʽ
|
||||||
|
|
@ -71,44 +106,15 @@ namespace easy2d
|
||||||
TextAntialias mode
|
TextAntialias mode
|
||||||
);
|
);
|
||||||
|
|
||||||
Status const& GetStatus() const;
|
// <20>零뺌궝拷츠똑
|
||||||
|
void SetOpacity(
|
||||||
HRESULT CreateResources(
|
float opacity
|
||||||
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
|
|
||||||
);
|
);
|
||||||
|
|
||||||
HRESULT SetTransform(
|
HRESULT SetTransform(
|
||||||
const Matrix& matrix
|
const Matrix& matrix
|
||||||
);
|
);
|
||||||
|
|
||||||
HRESULT SetOpacity(
|
|
||||||
float opacity
|
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT SetTextStyle(
|
HRESULT SetTextStyle(
|
||||||
const Color& color,
|
const Color& color,
|
||||||
bool has_outline,
|
bool has_outline,
|
||||||
|
|
@ -117,31 +123,6 @@ namespace easy2d
|
||||||
StrokeStyle outline_stroke
|
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(
|
HRESULT PushClip(
|
||||||
const Matrix& clip_matrix,
|
const Matrix& clip_matrix,
|
||||||
const Size& clip_size
|
const Size& clip_size
|
||||||
|
|
@ -150,46 +131,35 @@ namespace easy2d
|
||||||
HRESULT PopClip();
|
HRESULT PopClip();
|
||||||
|
|
||||||
HRESULT PushLayer(
|
HRESULT PushLayer(
|
||||||
D2DLayerPtr const& layer,
|
ComPtr<ID2D1Layer> const& layer,
|
||||||
LayerProperties const& properties
|
LayerProperties const& properties
|
||||||
);
|
);
|
||||||
|
|
||||||
HRESULT PopLayer();
|
HRESULT PopLayer();
|
||||||
|
|
||||||
HRESULT GetSize(
|
private:
|
||||||
Size& size
|
Renderer();
|
||||||
);
|
|
||||||
|
|
||||||
HRESULT Resize(
|
~Renderer();
|
||||||
UINT32 width,
|
|
||||||
UINT32 height
|
|
||||||
);
|
|
||||||
|
|
||||||
void ClearImageCache();
|
HRESULT CreateDeviceResources();
|
||||||
|
|
||||||
D2DHwndRenderTargetPtr const& GetRenderTarget() const;
|
HRESULT HandleDeviceLost();
|
||||||
|
|
||||||
D2DSolidColorBrushPtr const& GetSolidBrush() const;
|
private:
|
||||||
|
float opacity_;
|
||||||
|
bool antialias_;
|
||||||
|
unsigned long ref_count_;
|
||||||
|
|
||||||
protected:
|
TextAntialias text_antialias_;
|
||||||
RenderSystem();
|
D2D1_COLOR_F clear_color_;
|
||||||
|
RenderStatus status_;
|
||||||
|
|
||||||
~RenderSystem();
|
ComPtr<DeviceResources> device_resources_;
|
||||||
|
ComPtr<ID2D1Factory1> factory_;
|
||||||
protected:
|
ComPtr<ID2D1DeviceContext> device_context_;
|
||||||
bool debug_;
|
ComPtr<ID2D1DrawingStateBlock> drawing_state_block_;
|
||||||
bool window_occluded_;
|
ComPtr<ITextRenderer> text_renderer_;
|
||||||
bool vsync_enabled_;
|
ComPtr<ID2D1SolidColorBrush> solid_color_brush_;
|
||||||
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_;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
HINSTANCE hinst = GetModuleHandleW(nullptr);
|
||||||
WNDCLASSEX wcex = { 0 };
|
WNDCLASSEX wcex = { 0 };
|
||||||
wcex.cbSize = sizeof(WNDCLASSEX);
|
wcex.cbSize = sizeof(WNDCLASSEX);
|
||||||
|
|
@ -160,8 +156,6 @@ namespace easy2d
|
||||||
|
|
||||||
void Window::Destroy()
|
void Window::Destroy()
|
||||||
{
|
{
|
||||||
E2D_LOG(L"Destroying window");
|
|
||||||
|
|
||||||
if (is_fullscreen_)
|
if (is_fullscreen_)
|
||||||
RestoreResolution(device_name_);
|
RestoreResolution(device_name_);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,7 @@ namespace easy2d
|
||||||
int height,
|
int height,
|
||||||
LPCWSTR icon,
|
LPCWSTR icon,
|
||||||
bool fullscreen,
|
bool fullscreen,
|
||||||
WNDPROC proc,
|
WNDPROC proc
|
||||||
bool debug
|
|
||||||
);
|
);
|
||||||
|
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
|
||||||
|
|
@ -18,57 +18,134 @@
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
#include "Factory.h"
|
#include "DeviceResources.h"
|
||||||
#include "logs.h"
|
#include "../core/Image.h"
|
||||||
#include "modules.h"
|
#include "../core/modules.h"
|
||||||
#include "Transform.hpp"
|
#include "../core/logs.h"
|
||||||
|
|
||||||
namespace easy2d
|
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;
|
D2D1_FACTORY_OPTIONS options;
|
||||||
options.debugLevel = debug ? D2D1_DEBUG_LEVEL_INFORMATION : D2D1_DEBUG_LEVEL_NONE;
|
ZeroMemory(&options, sizeof(D2D1_FACTORY_OPTIONS));
|
||||||
HRESULT hr = modules::DirectX::Get().D2D1CreateFactory(
|
#ifdef E2D_DEBUG
|
||||||
|
options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
hr = modules::DirectX::Get().D2D1CreateFactory(
|
||||||
D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||||
__uuidof(ID2D1Factory),
|
__uuidof(ID2D1Factory1),
|
||||||
&options,
|
&options,
|
||||||
reinterpret_cast<void**>(&factory_)
|
reinterpret_cast<void**>(&d2d_factory)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
d2d_factory_ = d2d_factory;
|
||||||
|
|
||||||
CoCreateInstance(
|
CoCreateInstance(
|
||||||
CLSID_WICImagingFactory,
|
CLSID_WICImagingFactory,
|
||||||
nullptr,
|
nullptr,
|
||||||
CLSCTX_INPROC_SERVER,
|
CLSCTX_INPROC_SERVER,
|
||||||
__uuidof(IWICImagingFactory),
|
__uuidof(IWICImagingFactory),
|
||||||
reinterpret_cast<void**>(&imaging_factory_)
|
reinterpret_cast<void**>(&imaging_factory)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
|
imaging_factory_ = imaging_factory;
|
||||||
|
|
||||||
modules::DirectX::Get().DWriteCreateFactory(
|
modules::DirectX::Get().DWriteCreateFactory(
|
||||||
DWRITE_FACTORY_TYPE_SHARED,
|
DWRITE_FACTORY_TYPE_SHARED,
|
||||||
__uuidof(IDWriteFactory),
|
__uuidof(IDWriteFactory),
|
||||||
reinterpret_cast<IUnknown**>(&write_factory_)
|
reinterpret_cast<IUnknown**>(&dwrite_factory)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
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,
|
D2D1_CAP_STYLE_FLAT,
|
||||||
D2D1_CAP_STYLE_FLAT,
|
D2D1_CAP_STYLE_FLAT,
|
||||||
|
|
@ -78,101 +155,89 @@ namespace easy2d
|
||||||
0.0f
|
0.0f
|
||||||
);
|
);
|
||||||
|
|
||||||
hr = factory_->CreateStrokeStyle(
|
hr = d2d_factory_->CreateStrokeStyle(
|
||||||
stroke_style,
|
stroke_style,
|
||||||
nullptr,
|
nullptr,
|
||||||
0,
|
0,
|
||||||
&miter_stroke_style_
|
&d2d_miter_stroke_style
|
||||||
);
|
);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL;
|
stroke_style.lineJoin = D2D1_LINE_JOIN_BEVEL;
|
||||||
hr = factory_->CreateStrokeStyle(
|
hr = d2d_factory_->CreateStrokeStyle(
|
||||||
stroke_style,
|
stroke_style,
|
||||||
nullptr,
|
nullptr,
|
||||||
0,
|
0,
|
||||||
&bevel_stroke_style_
|
&d2d_bevel_stroke_style
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND;
|
stroke_style.lineJoin = D2D1_LINE_JOIN_ROUND;
|
||||||
hr = factory_->CreateStrokeStyle(
|
hr = d2d_factory_->CreateStrokeStyle(
|
||||||
stroke_style,
|
stroke_style,
|
||||||
nullptr,
|
nullptr,
|
||||||
0,
|
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;
|
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();
|
HRESULT hr = device->CreateDeviceContext(
|
||||||
imaging_factory_.Reset();
|
D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
|
||||||
write_factory_.Reset();
|
&d2d_device_ctx
|
||||||
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
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
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;
|
return hr;
|
||||||
IntrusivePtr<IWICBitmapFrameDecode> source;
|
}
|
||||||
IntrusivePtr<IWICStream> stream;
|
|
||||||
IntrusivePtr<IWICFormatConverter> converter;
|
void D2DDeviceResources::SetTargetBitmap(ComPtr<ID2D1Bitmap1> const& target)
|
||||||
IntrusivePtr<ID2D1Bitmap> bitmap_tmp;
|
{
|
||||||
|
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(
|
HRESULT hr = imaging_factory_->CreateDecoderFromFilename(
|
||||||
file_path.c_str(),
|
file_path.c_str(),
|
||||||
|
|
@ -207,7 +272,7 @@ namespace easy2d
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
hr = rt->CreateBitmapFromWicBitmap(
|
hr = d2d_device_context_->CreateBitmapFromWicBitmap(
|
||||||
converter.Get(),
|
converter.Get(),
|
||||||
nullptr,
|
nullptr,
|
||||||
&bitmap_tmp
|
&bitmap_tmp
|
||||||
|
|
@ -215,23 +280,31 @@ namespace easy2d
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
bitmap = bitmap_tmp;
|
bitmap = bitmap_tmp;
|
||||||
|
bitmap_cache_.insert(std::make_pair(hash_code, bitmap));
|
||||||
|
}
|
||||||
|
|
||||||
return hr;
|
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;
|
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;
|
ComPtr<IWICBitmapDecoder> decoder;
|
||||||
IntrusivePtr<IWICBitmapFrameDecode> source;
|
ComPtr<IWICBitmapFrameDecode> source;
|
||||||
IntrusivePtr<IWICStream> stream;
|
ComPtr<IWICStream> stream;
|
||||||
IntrusivePtr<IWICFormatConverter> converter;
|
ComPtr<IWICFormatConverter> converter;
|
||||||
IntrusivePtr<ID2D1Bitmap> bitmap_tmp;
|
ComPtr<ID2D1Bitmap> bitmap_tmp;
|
||||||
|
|
||||||
// ¼ÓÔØ×ÊÔ´
|
// ¼ÓÔØ×ÊÔ´
|
||||||
LPVOID buffer;
|
LPVOID buffer;
|
||||||
|
|
@ -286,7 +359,7 @@ namespace easy2d
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
hr = rt->CreateBitmapFromWicBitmap(
|
hr = d2d_device_context_->CreateBitmapFromWicBitmap(
|
||||||
converter.Get(),
|
converter.Get(),
|
||||||
nullptr,
|
nullptr,
|
||||||
&bitmap_tmp
|
&bitmap_tmp
|
||||||
|
|
@ -296,105 +369,19 @@ namespace easy2d
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
bitmap = bitmap_tmp;
|
bitmap = bitmap_tmp;
|
||||||
|
bitmap_cache_.insert(std::make_pair(hash_code, bitmap));
|
||||||
}
|
}
|
||||||
|
|
||||||
return hr;
|
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;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
D2DRectangleGeometryPtr rectangle;
|
ComPtr<IDWriteTextFormat> text_format_tmp;
|
||||||
HRESULT hr = factory_->CreateRectangleGeometry(
|
HRESULT hr = dwrite_factory_->CreateTextFormat(
|
||||||
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(
|
|
||||||
font.family.c_str(),
|
font.family.c_str(),
|
||||||
nullptr,
|
nullptr,
|
||||||
DWRITE_FONT_WEIGHT(font.weight),
|
DWRITE_FONT_WEIGHT(font.weight),
|
||||||
|
|
@ -426,20 +413,20 @@ namespace easy2d
|
||||||
return hr;
|
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;
|
return E_UNEXPECTED;
|
||||||
|
|
||||||
text_layout = nullptr;
|
text_layout = nullptr;
|
||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
D2DTextLayoutPtr text_layout_tmp;
|
ComPtr<IDWriteTextLayout> text_layout_tmp;
|
||||||
UINT32 length = static_cast<UINT32>(text.length());
|
UINT32 length = static_cast<UINT32>(text.length());
|
||||||
|
|
||||||
if (text_style.wrap)
|
if (text_style.wrap)
|
||||||
{
|
{
|
||||||
hr = write_factory_->CreateTextLayout(
|
hr = dwrite_factory_->CreateTextLayout(
|
||||||
text.c_str(),
|
text.c_str(),
|
||||||
length,
|
length,
|
||||||
text_format.Get(),
|
text_format.Get(),
|
||||||
|
|
@ -450,7 +437,7 @@ namespace easy2d
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hr = write_factory_->CreateTextLayout(
|
hr = dwrite_factory_->CreateTextLayout(
|
||||||
text.c_str(),
|
text.c_str(),
|
||||||
length,
|
length,
|
||||||
text_format.Get(),
|
text_format.Get(),
|
||||||
|
|
@ -468,7 +455,7 @@ namespace easy2d
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
text_layout_tmp = nullptr;
|
text_layout_tmp = nullptr;
|
||||||
hr = write_factory_->CreateTextLayout(
|
hr = dwrite_factory_->CreateTextLayout(
|
||||||
text.c_str(),
|
text.c_str(),
|
||||||
length,
|
length,
|
||||||
text_format.Get(),
|
text_format.Get(),
|
||||||
|
|
@ -507,21 +494,20 @@ namespace easy2d
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
D2DStrokeStylePtr const& Factory::GetStrokeStyle(StrokeStyle stroke) const
|
void D2DDeviceResources::ClearImageCache()
|
||||||
|
{
|
||||||
|
bitmap_cache_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
ID2D1StrokeStyle* D2DDeviceResources::GetStrokeStyle(StrokeStyle stroke) const
|
||||||
{
|
{
|
||||||
switch (stroke)
|
switch (stroke)
|
||||||
{
|
{
|
||||||
case StrokeStyle::Miter:
|
case StrokeStyle::Miter: return d2d_miter_stroke_style_.Get(); break;
|
||||||
return miter_stroke_style_;
|
case StrokeStyle::Bevel: return d2d_bevel_stroke_style_.Get(); break;
|
||||||
break;
|
case StrokeStyle::Round: return d2d_round_stroke_style_.Get(); break;
|
||||||
case StrokeStyle::Bevel:
|
|
||||||
return bevel_stroke_style_;
|
|
||||||
break;
|
|
||||||
case StrokeStyle::Round:
|
|
||||||
return round_stroke_style_;
|
|
||||||
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
|
namespace easy2d
|
||||||
{
|
{
|
||||||
class TextRendererImpl
|
class TextRenderer
|
||||||
: public ITextRenderer
|
: public ITextRenderer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TextRendererImpl(
|
TextRenderer(
|
||||||
ID2D1Factory* pD2DFactory,
|
ID2D1RenderTarget* pRT
|
||||||
ID2D1RenderTarget* pRT,
|
|
||||||
ID2D1SolidColorBrush* pBrush
|
|
||||||
);
|
);
|
||||||
|
|
||||||
~TextRendererImpl();
|
~TextRenderer();
|
||||||
|
|
||||||
|
STDMETHOD(CreateDeviceResources)();
|
||||||
|
|
||||||
STDMETHOD_(void, SetTextStyle)(
|
STDMETHOD_(void, SetTextStyle)(
|
||||||
CONST D2D1_COLOR_F &fillColor,
|
CONST D2D1_COLOR_F &fillColor,
|
||||||
|
|
@ -109,7 +109,7 @@ namespace easy2d
|
||||||
D2D1_COLOR_F sOutlineColor_;
|
D2D1_COLOR_F sOutlineColor_;
|
||||||
FLOAT fOutlineWidth;
|
FLOAT fOutlineWidth;
|
||||||
BOOL bShowOutline_;
|
BOOL bShowOutline_;
|
||||||
ID2D1Factory* pD2DFactory_;
|
ID2D1Factory* pFactory_;
|
||||||
ID2D1RenderTarget* pRT_;
|
ID2D1RenderTarget* pRT_;
|
||||||
ID2D1SolidColorBrush* pBrush_;
|
ID2D1SolidColorBrush* pBrush_;
|
||||||
ID2D1StrokeStyle* pCurrStrokeStyle_;
|
ID2D1StrokeStyle* pCurrStrokeStyle_;
|
||||||
|
|
@ -117,43 +117,72 @@ namespace easy2d
|
||||||
|
|
||||||
HRESULT ITextRenderer::Create(
|
HRESULT ITextRenderer::Create(
|
||||||
ITextRenderer** ppTextRenderer,
|
ITextRenderer** ppTextRenderer,
|
||||||
ID2D1Factory* pD2DFactory,
|
ID2D1RenderTarget* pRT)
|
||||||
ID2D1RenderTarget* pRT,
|
|
||||||
ID2D1SolidColorBrush* pBrush)
|
|
||||||
{
|
{
|
||||||
*ppTextRenderer = new (std::nothrow) TextRendererImpl(pD2DFactory, pRT, pBrush);
|
HRESULT hr = E_FAIL;
|
||||||
if (*ppTextRenderer)
|
|
||||||
|
if (ppTextRenderer)
|
||||||
{
|
{
|
||||||
(*ppTextRenderer)->AddRef();
|
TextRenderer* pTextRenderer = new (std::nothrow) TextRenderer(pRT);
|
||||||
return S_OK;
|
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)
|
: cRefCount_(0)
|
||||||
, pD2DFactory_(pD2DFactory)
|
, pFactory_(NULL)
|
||||||
, pRT_(pRT)
|
, pRT_(pRT)
|
||||||
, pBrush_(pBrush)
|
, pBrush_(NULL)
|
||||||
, sFillColor_()
|
, sFillColor_()
|
||||||
, sOutlineColor_()
|
, sOutlineColor_()
|
||||||
, fOutlineWidth(1)
|
, fOutlineWidth(1)
|
||||||
, bShowOutline_(TRUE)
|
, bShowOutline_(TRUE)
|
||||||
, pCurrStrokeStyle_(nullptr)
|
, pCurrStrokeStyle_(NULL)
|
||||||
{
|
{
|
||||||
pD2DFactory->AddRef();
|
pRT_->AddRef();
|
||||||
pRT->AddRef();
|
pRT_->GetFactory(&pFactory_);
|
||||||
pBrush->AddRef();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TextRendererImpl::~TextRendererImpl()
|
TextRenderer::~TextRenderer()
|
||||||
{
|
{
|
||||||
SafeRelease(pD2DFactory_);
|
DX::SafeRelease(pFactory_);
|
||||||
SafeRelease(pRT_);
|
DX::SafeRelease(pRT_);
|
||||||
SafeRelease(pBrush_);
|
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,
|
CONST D2D1_COLOR_F &fillColor,
|
||||||
BOOL outline,
|
BOOL outline,
|
||||||
CONST D2D1_COLOR_F &outlineColor,
|
CONST D2D1_COLOR_F &outlineColor,
|
||||||
|
|
@ -167,7 +196,7 @@ namespace easy2d
|
||||||
pCurrStrokeStyle_ = outlineJoin;
|
pCurrStrokeStyle_ = outlineJoin;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP TextRendererImpl::DrawGlyphRun(
|
STDMETHODIMP TextRenderer::DrawGlyphRun(
|
||||||
__maybenull void* clientDrawingContext,
|
__maybenull void* clientDrawingContext,
|
||||||
FLOAT baselineOriginX,
|
FLOAT baselineOriginX,
|
||||||
FLOAT baselineOriginY,
|
FLOAT baselineOriginY,
|
||||||
|
|
@ -183,12 +212,12 @@ namespace easy2d
|
||||||
|
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
ID2D1PathGeometry* pPathGeometry = nullptr;
|
ID2D1PathGeometry* pPathGeometry = NULL;
|
||||||
hr = pD2DFactory_->CreatePathGeometry(
|
hr = pFactory_->CreatePathGeometry(
|
||||||
&pPathGeometry
|
&pPathGeometry
|
||||||
);
|
);
|
||||||
|
|
||||||
ID2D1GeometrySink* pSink = nullptr;
|
ID2D1GeometrySink* pSink = NULL;
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
hr = pPathGeometry->Open(
|
hr = pPathGeometry->Open(
|
||||||
|
|
@ -221,10 +250,10 @@ namespace easy2d
|
||||||
baselineOriginX, baselineOriginY
|
baselineOriginX, baselineOriginY
|
||||||
);
|
);
|
||||||
|
|
||||||
ID2D1TransformedGeometry* pTransformedGeometry = nullptr;
|
ID2D1TransformedGeometry* pTransformedGeometry = NULL;
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
hr = pD2DFactory_->CreateTransformedGeometry(
|
hr = pFactory_->CreateTransformedGeometry(
|
||||||
pPathGeometry,
|
pPathGeometry,
|
||||||
&matrix,
|
&matrix,
|
||||||
&pTransformedGeometry
|
&pTransformedGeometry
|
||||||
|
|
@ -253,14 +282,14 @@ namespace easy2d
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
SafeRelease(pPathGeometry);
|
DX::SafeRelease(pPathGeometry);
|
||||||
SafeRelease(pSink);
|
DX::SafeRelease(pSink);
|
||||||
SafeRelease(pTransformedGeometry);
|
DX::SafeRelease(pTransformedGeometry);
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP TextRendererImpl::DrawUnderline(
|
STDMETHODIMP TextRenderer::DrawUnderline(
|
||||||
__maybenull void* clientDrawingContext,
|
__maybenull void* clientDrawingContext,
|
||||||
FLOAT baselineOriginX,
|
FLOAT baselineOriginX,
|
||||||
FLOAT baselineOriginY,
|
FLOAT baselineOriginY,
|
||||||
|
|
@ -279,8 +308,8 @@ namespace easy2d
|
||||||
underline->offset + underline->thickness
|
underline->offset + underline->thickness
|
||||||
);
|
);
|
||||||
|
|
||||||
ID2D1RectangleGeometry* pRectangleGeometry = nullptr;
|
ID2D1RectangleGeometry* pRectangleGeometry = NULL;
|
||||||
hr = pD2DFactory_->CreateRectangleGeometry(
|
hr = pFactory_->CreateRectangleGeometry(
|
||||||
&rect,
|
&rect,
|
||||||
&pRectangleGeometry
|
&pRectangleGeometry
|
||||||
);
|
);
|
||||||
|
|
@ -291,10 +320,10 @@ namespace easy2d
|
||||||
baselineOriginX, baselineOriginY
|
baselineOriginX, baselineOriginY
|
||||||
);
|
);
|
||||||
|
|
||||||
ID2D1TransformedGeometry* pTransformedGeometry = nullptr;
|
ID2D1TransformedGeometry* pTransformedGeometry = NULL;
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
hr = pD2DFactory_->CreateTransformedGeometry(
|
hr = pFactory_->CreateTransformedGeometry(
|
||||||
pRectangleGeometry,
|
pRectangleGeometry,
|
||||||
&matrix,
|
&matrix,
|
||||||
&pTransformedGeometry
|
&pTransformedGeometry
|
||||||
|
|
@ -323,13 +352,13 @@ namespace easy2d
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
SafeRelease(pRectangleGeometry);
|
DX::SafeRelease(pRectangleGeometry);
|
||||||
SafeRelease(pTransformedGeometry);
|
DX::SafeRelease(pTransformedGeometry);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP TextRendererImpl::DrawStrikethrough(
|
STDMETHODIMP TextRenderer::DrawStrikethrough(
|
||||||
__maybenull void* clientDrawingContext,
|
__maybenull void* clientDrawingContext,
|
||||||
FLOAT baselineOriginX,
|
FLOAT baselineOriginX,
|
||||||
FLOAT baselineOriginY,
|
FLOAT baselineOriginY,
|
||||||
|
|
@ -348,8 +377,8 @@ namespace easy2d
|
||||||
strikethrough->offset + strikethrough->thickness
|
strikethrough->offset + strikethrough->thickness
|
||||||
);
|
);
|
||||||
|
|
||||||
ID2D1RectangleGeometry* pRectangleGeometry = nullptr;
|
ID2D1RectangleGeometry* pRectangleGeometry = NULL;
|
||||||
hr = pD2DFactory_->CreateRectangleGeometry(
|
hr = pFactory_->CreateRectangleGeometry(
|
||||||
&rect,
|
&rect,
|
||||||
&pRectangleGeometry
|
&pRectangleGeometry
|
||||||
);
|
);
|
||||||
|
|
@ -360,10 +389,10 @@ namespace easy2d
|
||||||
baselineOriginX, baselineOriginY
|
baselineOriginX, baselineOriginY
|
||||||
);
|
);
|
||||||
|
|
||||||
ID2D1TransformedGeometry* pTransformedGeometry = nullptr;
|
ID2D1TransformedGeometry* pTransformedGeometry = NULL;
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
hr = pD2DFactory_->CreateTransformedGeometry(
|
hr = pFactory_->CreateTransformedGeometry(
|
||||||
pRectangleGeometry,
|
pRectangleGeometry,
|
||||||
&matrix,
|
&matrix,
|
||||||
&pTransformedGeometry
|
&pTransformedGeometry
|
||||||
|
|
@ -392,13 +421,13 @@ namespace easy2d
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
SafeRelease(pRectangleGeometry);
|
DX::SafeRelease(pRectangleGeometry);
|
||||||
SafeRelease(pTransformedGeometry);
|
DX::SafeRelease(pTransformedGeometry);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP TextRendererImpl::DrawInlineObject(
|
STDMETHODIMP TextRenderer::DrawInlineObject(
|
||||||
__maybenull void* clientDrawingContext,
|
__maybenull void* clientDrawingContext,
|
||||||
FLOAT originX,
|
FLOAT originX,
|
||||||
FLOAT originY,
|
FLOAT originY,
|
||||||
|
|
@ -417,12 +446,12 @@ namespace easy2d
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP_(unsigned long) TextRendererImpl::AddRef()
|
STDMETHODIMP_(unsigned long) TextRenderer::AddRef()
|
||||||
{
|
{
|
||||||
return InterlockedIncrement(&cRefCount_);
|
return InterlockedIncrement(&cRefCount_);
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP_(unsigned long) TextRendererImpl::Release()
|
STDMETHODIMP_(unsigned long) TextRenderer::Release()
|
||||||
{
|
{
|
||||||
unsigned long newCount = InterlockedDecrement(&cRefCount_);
|
unsigned long newCount = InterlockedDecrement(&cRefCount_);
|
||||||
|
|
||||||
|
|
@ -435,7 +464,7 @@ namespace easy2d
|
||||||
return newCount;
|
return newCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP TextRendererImpl::IsPixelSnappingDisabled(
|
STDMETHODIMP TextRenderer::IsPixelSnappingDisabled(
|
||||||
__maybenull void* clientDrawingContext,
|
__maybenull void* clientDrawingContext,
|
||||||
__out BOOL* isDisabled)
|
__out BOOL* isDisabled)
|
||||||
{
|
{
|
||||||
|
|
@ -445,7 +474,7 @@ namespace easy2d
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP TextRendererImpl::GetCurrentTransform(
|
STDMETHODIMP TextRenderer::GetCurrentTransform(
|
||||||
__maybenull void* clientDrawingContext,
|
__maybenull void* clientDrawingContext,
|
||||||
__out DWRITE_MATRIX* transform)
|
__out DWRITE_MATRIX* transform)
|
||||||
{
|
{
|
||||||
|
|
@ -455,7 +484,7 @@ namespace easy2d
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP TextRendererImpl::GetPixelsPerDip(
|
STDMETHODIMP TextRenderer::GetPixelsPerDip(
|
||||||
__maybenull void* clientDrawingContext,
|
__maybenull void* clientDrawingContext,
|
||||||
__out FLOAT* pixelsPerDip)
|
__out FLOAT* pixelsPerDip)
|
||||||
{
|
{
|
||||||
|
|
@ -469,7 +498,7 @@ namespace easy2d
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
STDMETHODIMP TextRendererImpl::QueryInterface(
|
STDMETHODIMP TextRenderer::QueryInterface(
|
||||||
IID const& riid,
|
IID const& riid,
|
||||||
void** ppvObject)
|
void** ppvObject)
|
||||||
{
|
{
|
||||||
|
|
@ -487,7 +516,7 @@ namespace easy2d
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*ppvObject = nullptr;
|
*ppvObject = NULL;
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -19,7 +19,8 @@
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "d2dhelper.hpp"
|
#include "helper.hpp"
|
||||||
|
#include <dwrite.h>
|
||||||
|
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
{
|
{
|
||||||
|
|
@ -29,9 +30,7 @@ namespace easy2d
|
||||||
public:
|
public:
|
||||||
static E2D_API HRESULT Create(
|
static E2D_API HRESULT Create(
|
||||||
_Out_ ITextRenderer** ppTextRenderer,
|
_Out_ ITextRenderer** ppTextRenderer,
|
||||||
_In_ ID2D1Factory* pD2DFactory,
|
_In_ ID2D1RenderTarget* pRT
|
||||||
_In_ ID2D1RenderTarget* pRT,
|
|
||||||
_In_ ID2D1SolidColorBrush* pBrush
|
|
||||||
);
|
);
|
||||||
|
|
||||||
STDMETHOD_(void, SetTextStyle)(
|
STDMETHOD_(void, SetTextStyle)(
|
||||||
|
|
@ -43,5 +42,3 @@ namespace easy2d
|
||||||
) PURE;
|
) 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/GeometryNode.h"
|
||||||
#include "core/DebugNode.h"
|
#include "core/DebugNode.h"
|
||||||
|
|
||||||
#include "core/Factory.h"
|
|
||||||
#include "core/Application.h"
|
#include "core/Application.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -90,7 +89,7 @@
|
||||||
#include "math/ease.hpp"
|
#include "math/ease.hpp"
|
||||||
#include "math/vector.hpp"
|
#include "math/vector.hpp"
|
||||||
#include "math/rand.h"
|
#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
|
#pragma once
|
||||||
#include "vector.hpp"
|
#include "vector.hpp"
|
||||||
#include "Rect.hpp"
|
#include "Rect.hpp"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
{
|
{
|
||||||
namespace math
|
namespace math
|
||||||
{
|
{
|
||||||
struct E2D_API Matrix
|
struct Matrix
|
||||||
{
|
{
|
||||||
union
|
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>
|
template <typename T>
|
||||||
Matrix(T const& other)
|
Matrix(T const& other)
|
||||||
|
|
@ -59,7 +77,12 @@ namespace easy2d
|
||||||
m[i] = other[i];
|
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
|
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)
|
inline void Translate(const Vec2& v)
|
||||||
{
|
{
|
||||||
|
|
@ -107,46 +143,83 @@ namespace easy2d
|
||||||
return 0 != Determinant();
|
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& ()
|
static inline Matrix Translation(
|
||||||
{
|
|
||||||
return reinterpret_cast<D2D1_MATRIX_3X2_F&>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Matrix Translation(const Vec2& v);
|
|
||||||
|
|
||||||
static Matrix Translation(
|
|
||||||
float x,
|
float x,
|
||||||
float y
|
float y)
|
||||||
);
|
{
|
||||||
|
return Translation(Vec2(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
static Matrix Scaling(
|
static inline Matrix Scaling(
|
||||||
const Vec2& v,
|
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 x,
|
||||||
float y,
|
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,
|
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_x,
|
||||||
float angle_y,
|
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
|
namespace math
|
||||||
{
|
{
|
||||||
// 矩形
|
// 矩形
|
||||||
struct E2D_API Rect
|
struct Rect
|
||||||
{
|
{
|
||||||
Vec2 origin; // 左上角坐标
|
Vec2 origin; // 左上角坐标
|
||||||
Vec2 size; // 宽度和高度
|
Vec2 size; // 宽度和高度
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "../core/macros.h"
|
|
||||||
#include "constants.hpp"
|
#include "constants.hpp"
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
namespace math
|
namespace math
|
||||||
{
|
{
|
||||||
struct E2D_API Vec2
|
struct Vec2
|
||||||
{
|
{
|
||||||
float x;
|
float x;
|
||||||
float y;
|
float y;
|
||||||
|
|
@ -81,6 +81,11 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
return (x == other.x) && (y == other.y);
|
return (x == other.x) && (y == other.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool operator!= (const Vec2& other) const
|
||||||
|
{
|
||||||
|
return (x != other.x) || (y != other.y);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using Point = Vec2;
|
using Point = Vec2;
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Transcoder.h"
|
#include "Transcoder.h"
|
||||||
#include "../core/d2dhelper.hpp"
|
|
||||||
#include "../core/modules.h"
|
#include "../core/modules.h"
|
||||||
#include "../core/logs.h"
|
#include "../core/logs.h"
|
||||||
|
#include "../DX/helper.hpp"
|
||||||
#include <shlwapi.h>
|
#include <shlwapi.h>
|
||||||
|
|
||||||
namespace easy2d
|
namespace easy2d
|
||||||
|
|
@ -53,7 +53,7 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
IntrusivePtr<IMFSourceReader> reader;
|
ComPtr<IMFSourceReader> reader;
|
||||||
|
|
||||||
hr = modules::MediaFoundation::Get().MFCreateSourceReaderFromURL(
|
hr = modules::MediaFoundation::Get().MFCreateSourceReaderFromURL(
|
||||||
file_path.c_str(),
|
file_path.c_str(),
|
||||||
|
|
@ -73,9 +73,9 @@ namespace easy2d
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
IntrusivePtr<IStream> stream;
|
ComPtr<IStream> stream;
|
||||||
IntrusivePtr<IMFByteStream> byte_stream;
|
ComPtr<IMFByteStream> byte_stream;
|
||||||
IntrusivePtr<IMFSourceReader> reader;
|
ComPtr<IMFSourceReader> reader;
|
||||||
|
|
||||||
LPVOID buffer;
|
LPVOID buffer;
|
||||||
DWORD buffer_size;
|
DWORD buffer_size;
|
||||||
|
|
@ -119,8 +119,8 @@ namespace easy2d
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
DWORD max_stream_size = 0;
|
DWORD max_stream_size = 0;
|
||||||
|
|
||||||
IntrusivePtr<IMFMediaType> partial_type;
|
ComPtr<IMFMediaType> partial_type;
|
||||||
IntrusivePtr<IMFMediaType> uncompressed_type;
|
ComPtr<IMFMediaType> uncompressed_type;
|
||||||
|
|
||||||
hr = modules::MediaFoundation::Get().MFCreateMediaType(&partial_type);
|
hr = modules::MediaFoundation::Get().MFCreateMediaType(&partial_type);
|
||||||
|
|
||||||
|
|
@ -200,8 +200,8 @@ namespace easy2d
|
||||||
DWORD position = 0;
|
DWORD position = 0;
|
||||||
BYTE* data = new (std::nothrow) BYTE[max_stream_size];
|
BYTE* data = new (std::nothrow) BYTE[max_stream_size];
|
||||||
|
|
||||||
IntrusivePtr<IMFSample> sample;
|
ComPtr<IMFSample> sample;
|
||||||
IntrusivePtr<IMFMediaBuffer> buffer;
|
ComPtr<IMFMediaBuffer> buffer;
|
||||||
|
|
||||||
if (data == nullptr)
|
if (data == nullptr)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue