重做Window类和Renderer类单例模式
This commit is contained in:
parent
1d9f543eb8
commit
abaf59379a
|
|
@ -1,28 +1,35 @@
|
||||||
#include "..\e2dbase.h"
|
#include "..\e2dbase.h"
|
||||||
|
|
||||||
|
|
||||||
|
// GC 机制,用于自动销毁单例
|
||||||
|
e2d::GC e2d::GC::_instance;
|
||||||
|
|
||||||
|
e2d::GC::~GC()
|
||||||
|
{
|
||||||
|
// 删除所有单例
|
||||||
|
Game::destroyInstance();
|
||||||
|
Renderer::destroyInstance();
|
||||||
|
Window::destroyInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// GC 释放池的实现机制:
|
// GC 释放池的实现机制:
|
||||||
// Object 类中的引用计数(_refCount)在一定程度上防止了内存泄漏
|
// Object 类中的引用计数(_refCount)在一定程度上防止了内存泄漏
|
||||||
// 它记录了对象被使用的次数,当计数为 0 时,GC 会自动释放这个对象
|
// 它记录了对象被使用的次数,当计数为 0 时,GC 会自动释放这个对象
|
||||||
// 所有的 Object 对象都应在被使用时(例如 Text 添加到了场景中)
|
// 所有的 Object 对象都应在被使用时(例如 Text 添加到了场景中)
|
||||||
// 调用 retain 函数保证该对象不被删除,并在不再使用时调用 release 函数
|
// 调用 retain 函数保证该对象不被删除,并在不再使用时调用 release 函数
|
||||||
|
|
||||||
// 对象管理池
|
|
||||||
static std::set<e2d::Object*> s_vObjectPool;
|
|
||||||
// 标志释放池执行状态
|
|
||||||
static bool s_bNotifyed = false;
|
|
||||||
|
|
||||||
void e2d::GC::__update()
|
void e2d::GC::__update()
|
||||||
{
|
{
|
||||||
if (!s_bNotifyed) return;
|
if (!_notifyed) return;
|
||||||
|
|
||||||
s_bNotifyed = false;
|
_notifyed = false;
|
||||||
for (auto iter = s_vObjectPool.begin(); iter != s_vObjectPool.end();)
|
for (auto iter = _pool.begin(); iter != _pool.end();)
|
||||||
{
|
{
|
||||||
if ((*iter)->getRefCount() <= 0)
|
if ((*iter)->getRefCount() <= 0)
|
||||||
{
|
{
|
||||||
(*iter)->onDestroy();
|
(*iter)->onDestroy();
|
||||||
delete (*iter);
|
delete (*iter);
|
||||||
iter = s_vObjectPool.erase(iter);
|
iter = _pool.erase(iter);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -31,26 +38,31 @@ void e2d::GC::__update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::GC::__clear()
|
void e2d::GC::clear()
|
||||||
{
|
{
|
||||||
for (auto pObj : s_vObjectPool)
|
for (auto pObj : _pool)
|
||||||
{
|
{
|
||||||
delete pObj;
|
delete pObj;
|
||||||
}
|
}
|
||||||
s_vObjectPool.clear();
|
_pool.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::GC::__add(e2d::Object * pObject)
|
void e2d::GC::addObject(e2d::Object * pObject)
|
||||||
{
|
{
|
||||||
if (pObject)
|
if (pObject)
|
||||||
{
|
{
|
||||||
s_vObjectPool.insert(pObject);
|
_pool.insert(pObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e2d::GC * e2d::GC::getInstance()
|
||||||
|
{
|
||||||
|
return &_instance;
|
||||||
|
}
|
||||||
|
|
||||||
void e2d::GC::notify()
|
void e2d::GC::notify()
|
||||||
{
|
{
|
||||||
s_bNotifyed = true;
|
_notifyed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::GC::flush()
|
void e2d::GC::flush()
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,10 @@ e2d::Game::Game()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
e2d::Game::~Game()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
e2d::Game * e2d::Game::getInstance()
|
e2d::Game * e2d::Game::getInstance()
|
||||||
{
|
{
|
||||||
if (!_instance)
|
if (!_instance)
|
||||||
|
|
@ -20,6 +24,15 @@ e2d::Game * e2d::Game::getInstance()
|
||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void e2d::Game::destroyInstance()
|
||||||
|
{
|
||||||
|
if (_instance)
|
||||||
|
{
|
||||||
|
delete _instance;
|
||||||
|
_instance = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool e2d::Game::init(const String& mutexName)
|
bool e2d::Game::init(const String& mutexName)
|
||||||
{
|
{
|
||||||
if (_initialized)
|
if (_initialized)
|
||||||
|
|
@ -41,7 +54,7 @@ bool e2d::Game::init(const String& mutexName)
|
||||||
else if (::GetLastError() == ERROR_ALREADY_EXISTS)
|
else if (::GetLastError() == ERROR_ALREADY_EXISTS)
|
||||||
{
|
{
|
||||||
// 如果程序已经存在并且正在运行,弹窗提示
|
// 如果程序已经存在并且正在运行,弹窗提示
|
||||||
Window::info(L"游戏已在其他窗口中打开!", L"提示");
|
Window::getInstance()->info(L"游戏已在其他窗口中打开!", L"提示");
|
||||||
// 关闭进程互斥体
|
// 关闭进程互斥体
|
||||||
::CloseHandle(hMutex);
|
::CloseHandle(hMutex);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -51,54 +64,15 @@ bool e2d::Game::init(const String& mutexName)
|
||||||
// 初始化 COM 组件
|
// 初始化 COM 组件
|
||||||
CoInitialize(nullptr);
|
CoInitialize(nullptr);
|
||||||
|
|
||||||
bool bRendererDevIndResInit = false,
|
bool bInputInit = false,
|
||||||
bWindowInit = false,
|
|
||||||
bRendererDevResInit = false,
|
|
||||||
bInputInit = false,
|
|
||||||
bMusicInit = false;
|
bMusicInit = false;
|
||||||
|
|
||||||
auto DestroyResources = [&]()
|
auto DestroyResources = [&]()
|
||||||
{
|
{
|
||||||
if (bRendererDevIndResInit) Renderer::__discardResources();
|
|
||||||
if (bWindowInit) Window::__init();
|
|
||||||
if (bRendererDevResInit) Renderer::__discardDeviceResources();
|
|
||||||
if (bInputInit) Input::__uninit();
|
if (bInputInit) Input::__uninit();
|
||||||
if (bMusicInit) Music::__uninit();
|
if (bMusicInit) Music::__uninit();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 创建设备无关资源
|
|
||||||
if (Renderer::__createDeviceIndependentResources())
|
|
||||||
{
|
|
||||||
bRendererDevIndResInit = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DestroyResources();
|
|
||||||
throw SystemException(L"渲染器设备无关资源创建失败");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化窗口
|
|
||||||
if (Window::__init())
|
|
||||||
{
|
|
||||||
bWindowInit = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DestroyResources();
|
|
||||||
throw SystemException(L"初始化窗口失败");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建设备相关资源
|
|
||||||
if (Renderer::__createDeviceResources())
|
|
||||||
{
|
|
||||||
bRendererDevResInit = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DestroyResources();
|
|
||||||
throw SystemException(L"渲染器设备相关资源创建失败");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 初始化 DirectInput
|
// 初始化 DirectInput
|
||||||
if (Input::__init())
|
if (Input::__init())
|
||||||
{
|
{
|
||||||
|
|
@ -141,14 +115,17 @@ void e2d::Game::start(bool cleanup)
|
||||||
throw Exception(L"开始游戏前未进行初始化");
|
throw Exception(L"开始游戏前未进行初始化");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto window = Window::getInstance();
|
||||||
|
auto renderer = Renderer::getInstance();
|
||||||
|
|
||||||
// 初始化场景管理器
|
// 初始化场景管理器
|
||||||
SceneManager::__init();
|
SceneManager::__init();
|
||||||
// 显示窗口
|
// 显示窗口
|
||||||
::ShowWindow(Window::getHWnd(), SW_SHOWNORMAL);
|
::ShowWindow(window->getHWnd(), SW_SHOWNORMAL);
|
||||||
// 刷新窗口内容
|
// 刷新窗口内容
|
||||||
::UpdateWindow(Window::getHWnd());
|
::UpdateWindow(window->getHWnd());
|
||||||
// 处理窗口消息
|
// 处理窗口消息
|
||||||
Window::__poll();
|
window->__poll();
|
||||||
// 初始化计时
|
// 初始化计时
|
||||||
Time::__init();
|
Time::__init();
|
||||||
|
|
||||||
|
|
@ -157,7 +134,7 @@ void e2d::Game::start(bool cleanup)
|
||||||
while (!_ended)
|
while (!_ended)
|
||||||
{
|
{
|
||||||
// 处理窗口消息
|
// 处理窗口消息
|
||||||
Window::__poll();
|
window->__poll();
|
||||||
// 刷新时间
|
// 刷新时间
|
||||||
Time::__updateNow();
|
Time::__updateNow();
|
||||||
|
|
||||||
|
|
@ -168,14 +145,14 @@ void e2d::Game::start(bool cleanup)
|
||||||
Timer::__update(); // 更新定时器
|
Timer::__update(); // 更新定时器
|
||||||
ActionManager::__update(); // 更新动作管理器
|
ActionManager::__update(); // 更新动作管理器
|
||||||
SceneManager::__update(); // 更新场景内容
|
SceneManager::__update(); // 更新场景内容
|
||||||
Renderer::__render(); // 渲染游戏画面
|
renderer->__render(); // 渲染游戏画面
|
||||||
|
|
||||||
Time::__updateLast(); // 刷新时间信息
|
Time::__updateLast(); // 刷新时间信息
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Time::__sleep(); // 挂起线程
|
Time::__sleep(); // 挂起线程
|
||||||
GC::__update(); // 刷新内存池
|
GC::getInstance()->__update(); // 刷新内存池
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -236,8 +213,6 @@ void e2d::Game::cleanup()
|
||||||
ActionManager::__uninit();
|
ActionManager::__uninit();
|
||||||
// 回收音乐播放器资源
|
// 回收音乐播放器资源
|
||||||
Player::__uninit();
|
Player::__uninit();
|
||||||
// 删除所有对象
|
|
||||||
GC::__clear();
|
|
||||||
// 清空图片缓存
|
// 清空图片缓存
|
||||||
Image::clearCache();
|
Image::clearCache();
|
||||||
// 回收音乐相关资源
|
// 回收音乐相关资源
|
||||||
|
|
@ -246,21 +221,10 @@ void e2d::Game::cleanup()
|
||||||
Timer::__uninit();
|
Timer::__uninit();
|
||||||
// 关闭输入
|
// 关闭输入
|
||||||
Input::__uninit();
|
Input::__uninit();
|
||||||
// 回收渲染相关资源
|
// 删除所有对象
|
||||||
Renderer::__discardResources();
|
GC::getInstance()->clear();
|
||||||
// 销毁窗口
|
|
||||||
Window::__uninit();
|
|
||||||
|
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
|
|
||||||
_initialized = false;
|
_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Game::destroy()
|
|
||||||
{
|
|
||||||
if (_instance)
|
|
||||||
{
|
|
||||||
delete _instance;
|
|
||||||
_instance = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,8 @@ bool Input::__init()
|
||||||
nullptr
|
nullptr
|
||||||
);
|
);
|
||||||
|
|
||||||
|
auto window = Window::getInstance();
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
// 初始化键盘设备
|
// 初始化键盘设备
|
||||||
|
|
@ -49,7 +51,7 @@ bool Input::__init()
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
s_KeyboardDevice->SetCooperativeLevel(
|
s_KeyboardDevice->SetCooperativeLevel(
|
||||||
Window::getHWnd(),
|
window->getHWnd(),
|
||||||
DISCL_FOREGROUND | DISCL_NONEXCLUSIVE
|
DISCL_FOREGROUND | DISCL_NONEXCLUSIVE
|
||||||
);
|
);
|
||||||
s_KeyboardDevice->SetDataFormat(
|
s_KeyboardDevice->SetDataFormat(
|
||||||
|
|
@ -59,7 +61,7 @@ bool Input::__init()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Window::error(L"Keyboard not found!");
|
window->error(L"Keyboard not found!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -71,14 +73,14 @@ bool Input::__init()
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
s_MouseDevice->SetCooperativeLevel(Window::getHWnd(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
|
s_MouseDevice->SetCooperativeLevel(window->getHWnd(), DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
|
||||||
s_MouseDevice->SetDataFormat(&c_dfDIMouse);
|
s_MouseDevice->SetDataFormat(&c_dfDIMouse);
|
||||||
s_MouseDevice->Acquire();
|
s_MouseDevice->Acquire();
|
||||||
s_MouseDevice->Poll();
|
s_MouseDevice->Poll();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Window::error(L"Mouse not found!");
|
window->error(L"Mouse not found!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -141,7 +143,7 @@ void Input::__updateDeviceState()
|
||||||
}
|
}
|
||||||
|
|
||||||
GetCursorPos(&s_MousePosition);
|
GetCursorPos(&s_MousePosition);
|
||||||
ScreenToClient(Window::getHWnd(), &s_MousePosition);
|
ScreenToClient(Window::getInstance()->getHWnd(), &s_MousePosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Input::isDown(Key key)
|
bool Input::isDown(Key key)
|
||||||
|
|
|
||||||
|
|
@ -2,163 +2,66 @@
|
||||||
#include "..\e2dmanager.h"
|
#include "..\e2dmanager.h"
|
||||||
#include "..\e2dnode.h"
|
#include "..\e2dnode.h"
|
||||||
|
|
||||||
static bool s_bShowFps = false;
|
|
||||||
static float s_fDpiScaleX = 0;
|
|
||||||
static float s_fDpiScaleY = 0;
|
|
||||||
static IDWriteTextFormat * s_pTextFormat = nullptr;
|
|
||||||
static ID2D1Factory * s_pDirect2dFactory = nullptr;
|
|
||||||
static ID2D1HwndRenderTarget * s_pRenderTarget = nullptr;
|
|
||||||
static ID2D1SolidColorBrush * s_pSolidBrush = nullptr;
|
|
||||||
static IWICImagingFactory * s_pIWICFactory = nullptr;
|
|
||||||
static IDWriteFactory * s_pDWriteFactory = nullptr;
|
|
||||||
static e2d::TextRenderer * s_pTextRenderer = nullptr;
|
|
||||||
static ID2D1StrokeStyle * s_pMiterStrokeStyle = nullptr;
|
|
||||||
static ID2D1StrokeStyle * s_pBevelStrokeStyle = nullptr;
|
|
||||||
static ID2D1StrokeStyle * s_pRoundStrokeStyle = nullptr;
|
|
||||||
static D2D1_COLOR_F s_nClearColor = D2D1::ColorF(D2D1::ColorF::Black);
|
|
||||||
|
|
||||||
|
e2d::Renderer* e2d::Renderer::_instance = nullptr;
|
||||||
|
ID2D1Factory* e2d::Renderer::_d2dFactory = nullptr;
|
||||||
|
IWICImagingFactory* e2d::Renderer::_imagingFactory = nullptr;
|
||||||
|
IDWriteFactory* e2d::Renderer::_writeFactory = nullptr;
|
||||||
|
IDWriteTextFormat* e2d::Renderer::_textFormat = nullptr;
|
||||||
|
ID2D1StrokeStyle* e2d::Renderer::_miterStrokeStyle = nullptr;
|
||||||
|
ID2D1StrokeStyle* e2d::Renderer::_bevelStrokeStyle = nullptr;
|
||||||
|
ID2D1StrokeStyle* e2d::Renderer::_roundStrokeStyle = nullptr;
|
||||||
|
|
||||||
bool e2d::Renderer::__createDeviceIndependentResources()
|
e2d::Renderer * e2d::Renderer::getInstance()
|
||||||
{
|
{
|
||||||
// 创建设备无关资源,它们的生命周期和程序的时长相同
|
if (!_instance)
|
||||||
HRESULT hr = D2D1CreateFactory(
|
{
|
||||||
D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
_instance = new (std::nothrow) Renderer;
|
||||||
&s_pDirect2dFactory
|
}
|
||||||
);
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
// 工厂将返回当前的系统 DPI,这个值也将用来创建窗口
|
void e2d::Renderer::destroyInstance()
|
||||||
if (SUCCEEDED(hr))
|
{
|
||||||
|
if (_instance)
|
||||||
{
|
{
|
||||||
s_pDirect2dFactory->GetDesktopDpi(&s_fDpiScaleX, &s_fDpiScaleY);
|
delete _instance;
|
||||||
}
|
_instance = nullptr;
|
||||||
|
|
||||||
if (FAILED(hr))
|
SafeRelease(_textFormat);
|
||||||
{
|
SafeRelease(_d2dFactory);
|
||||||
throw SystemException(L"Create ID2D1Factory failed");
|
SafeRelease(_miterStrokeStyle);
|
||||||
}
|
SafeRelease(_bevelStrokeStyle);
|
||||||
else
|
SafeRelease(_roundStrokeStyle);
|
||||||
{
|
SafeRelease(_imagingFactory);
|
||||||
hr = s_pDirect2dFactory->CreateStrokeStyle(
|
SafeRelease(_writeFactory);
|
||||||
D2D1::StrokeStyleProperties(
|
|
||||||
D2D1_CAP_STYLE_FLAT,
|
|
||||||
D2D1_CAP_STYLE_FLAT,
|
|
||||||
D2D1_CAP_STYLE_FLAT,
|
|
||||||
D2D1_LINE_JOIN_MITER,
|
|
||||||
2.0f,
|
|
||||||
D2D1_DASH_STYLE_SOLID,
|
|
||||||
0.0f),
|
|
||||||
nullptr,
|
|
||||||
0,
|
|
||||||
&s_pMiterStrokeStyle
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (FAILED(hr))
|
e2d::Renderer::Renderer()
|
||||||
{
|
: _showFps(false)
|
||||||
throw SystemException(L"Create ID2D1StrokeStyle failed");
|
, _renderTarget(nullptr)
|
||||||
}
|
, _solidBrush(nullptr)
|
||||||
else
|
, _textRenderer(nullptr)
|
||||||
{
|
, _clearColor(D2D1::ColorF(D2D1::ColorF::Black))
|
||||||
hr = s_pDirect2dFactory->CreateStrokeStyle(
|
{
|
||||||
D2D1::StrokeStyleProperties(
|
this->__createDeviceResources();
|
||||||
D2D1_CAP_STYLE_FLAT,
|
}
|
||||||
D2D1_CAP_STYLE_FLAT,
|
|
||||||
D2D1_CAP_STYLE_FLAT,
|
|
||||||
D2D1_LINE_JOIN_BEVEL,
|
|
||||||
2.0f,
|
|
||||||
D2D1_DASH_STYLE_SOLID,
|
|
||||||
0.0f),
|
|
||||||
nullptr,
|
|
||||||
0,
|
|
||||||
&s_pBevelStrokeStyle
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
e2d::Renderer::~Renderer()
|
||||||
{
|
{
|
||||||
throw SystemException(L"Create ID2D1StrokeStyle failed");
|
SafeRelease(_renderTarget);
|
||||||
}
|
SafeRelease(_solidBrush);
|
||||||
else
|
SafeRelease(_textRenderer);
|
||||||
{
|
|
||||||
hr = s_pDirect2dFactory->CreateStrokeStyle(
|
|
||||||
D2D1::StrokeStyleProperties(
|
|
||||||
D2D1_CAP_STYLE_FLAT,
|
|
||||||
D2D1_CAP_STYLE_FLAT,
|
|
||||||
D2D1_CAP_STYLE_FLAT,
|
|
||||||
D2D1_LINE_JOIN_ROUND,
|
|
||||||
2.0f,
|
|
||||||
D2D1_DASH_STYLE_SOLID,
|
|
||||||
0.0f),
|
|
||||||
nullptr,
|
|
||||||
0,
|
|
||||||
&s_pRoundStrokeStyle
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
throw SystemException(L"Create ID2D1StrokeStyle failed");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 创建 WIC 绘图工厂,用于统一处理各种格式的图片
|
|
||||||
hr = CoCreateInstance(
|
|
||||||
CLSID_WICImagingFactory,
|
|
||||||
nullptr,
|
|
||||||
CLSCTX_INPROC_SERVER,
|
|
||||||
IID_IWICImagingFactory,
|
|
||||||
reinterpret_cast<void**>(&s_pIWICFactory)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
throw SystemException(L"Create IWICImagingFactory failed");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 创建 DirectWrite 工厂
|
|
||||||
hr = DWriteCreateFactory(
|
|
||||||
DWRITE_FACTORY_TYPE_SHARED,
|
|
||||||
__uuidof(IDWriteFactory),
|
|
||||||
reinterpret_cast<IUnknown**>(&s_pDWriteFactory)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
throw SystemException(L"Create IDWriteFactory failed");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 创建文本格式化对象
|
|
||||||
hr = s_pDWriteFactory->CreateTextFormat(
|
|
||||||
L"",
|
|
||||||
nullptr,
|
|
||||||
DWRITE_FONT_WEIGHT_NORMAL,
|
|
||||||
DWRITE_FONT_STYLE_NORMAL,
|
|
||||||
DWRITE_FONT_STRETCH_NORMAL,
|
|
||||||
20,
|
|
||||||
L"",
|
|
||||||
&s_pTextFormat
|
|
||||||
);
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
{
|
|
||||||
s_pTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return SUCCEEDED(hr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool e2d::Renderer::__createDeviceResources()
|
bool e2d::Renderer::__createDeviceResources()
|
||||||
{
|
{
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
|
||||||
if (!s_pRenderTarget)
|
if (!_renderTarget)
|
||||||
{
|
{
|
||||||
HWND hWnd = Window::getHWnd();
|
HWND hWnd = Window::getInstance()->getHWnd();
|
||||||
|
|
||||||
// 创建设备相关资源。这些资源应在 Direct3D 设备消失时重建,
|
// 创建设备相关资源。这些资源应在 Direct3D 设备消失时重建,
|
||||||
// 比如当 isVisiable 被修改,等等
|
// 比如当 isVisiable 被修改,等等
|
||||||
|
|
@ -171,12 +74,12 @@ bool e2d::Renderer::__createDeviceResources()
|
||||||
);
|
);
|
||||||
|
|
||||||
// 创建一个 Direct2D 渲染目标
|
// 创建一个 Direct2D 渲染目标
|
||||||
hr = s_pDirect2dFactory->CreateHwndRenderTarget(
|
hr = Renderer::getFactory()->CreateHwndRenderTarget(
|
||||||
D2D1::RenderTargetProperties(),
|
D2D1::RenderTargetProperties(),
|
||||||
D2D1::HwndRenderTargetProperties(
|
D2D1::HwndRenderTargetProperties(
|
||||||
hWnd,
|
hWnd,
|
||||||
size),
|
size),
|
||||||
&s_pRenderTarget
|
&_renderTarget
|
||||||
);
|
);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
|
@ -186,9 +89,9 @@ bool e2d::Renderer::__createDeviceResources()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 创建画刷
|
// 创建画刷
|
||||||
hr = s_pRenderTarget->CreateSolidColorBrush(
|
hr = _renderTarget->CreateSolidColorBrush(
|
||||||
D2D1::ColorF(D2D1::ColorF::White),
|
D2D1::ColorF(D2D1::ColorF::White),
|
||||||
&s_pSolidBrush
|
&_solidBrush
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -196,15 +99,6 @@ bool e2d::Renderer::__createDeviceResources()
|
||||||
{
|
{
|
||||||
throw SystemException(L"Create ID2D1SolidColorBrush failed");
|
throw SystemException(L"Create ID2D1SolidColorBrush failed");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// 创建自定义的文字渲染器
|
|
||||||
s_pTextRenderer = TextRenderer::Create(
|
|
||||||
s_pDirect2dFactory,
|
|
||||||
s_pRenderTarget,
|
|
||||||
s_pSolidBrush
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCEEDED(hr);
|
return SUCCEEDED(hr);
|
||||||
|
|
@ -212,26 +106,12 @@ bool e2d::Renderer::__createDeviceResources()
|
||||||
|
|
||||||
void e2d::Renderer::__discardDeviceResources()
|
void e2d::Renderer::__discardDeviceResources()
|
||||||
{
|
{
|
||||||
SafeRelease(s_pRenderTarget);
|
SafeRelease(_renderTarget);
|
||||||
SafeRelease(s_pSolidBrush);
|
SafeRelease(_solidBrush);
|
||||||
SafeRelease(s_pTextRenderer);
|
SafeRelease(_textRenderer);
|
||||||
SafeRelease(s_pMiterStrokeStyle);
|
SafeRelease(_miterStrokeStyle);
|
||||||
SafeRelease(s_pBevelStrokeStyle);
|
SafeRelease(_bevelStrokeStyle);
|
||||||
SafeRelease(s_pRoundStrokeStyle);
|
SafeRelease(_roundStrokeStyle);
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::Renderer::__discardResources()
|
|
||||||
{
|
|
||||||
SafeRelease(s_pTextFormat);
|
|
||||||
SafeRelease(s_pDirect2dFactory);
|
|
||||||
SafeRelease(s_pRenderTarget);
|
|
||||||
SafeRelease(s_pSolidBrush);
|
|
||||||
SafeRelease(s_pTextRenderer);
|
|
||||||
SafeRelease(s_pMiterStrokeStyle);
|
|
||||||
SafeRelease(s_pBevelStrokeStyle);
|
|
||||||
SafeRelease(s_pRoundStrokeStyle);
|
|
||||||
SafeRelease(s_pIWICFactory);
|
|
||||||
SafeRelease(s_pDWriteFactory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Renderer::__render()
|
void e2d::Renderer::__render()
|
||||||
|
|
@ -242,15 +122,15 @@ void e2d::Renderer::__render()
|
||||||
Renderer::__createDeviceResources();
|
Renderer::__createDeviceResources();
|
||||||
|
|
||||||
// 开始渲染
|
// 开始渲染
|
||||||
s_pRenderTarget->BeginDraw();
|
_renderTarget->BeginDraw();
|
||||||
// 使用背景色清空屏幕
|
// 使用背景色清空屏幕
|
||||||
s_pRenderTarget->Clear(s_nClearColor);
|
_renderTarget->Clear(_clearColor);
|
||||||
|
|
||||||
// 渲染场景
|
// 渲染场景
|
||||||
SceneManager::__render();
|
SceneManager::__render();
|
||||||
|
|
||||||
// 渲染 FPS
|
// 渲染 FPS
|
||||||
if (s_bShowFps && s_pTextFormat)
|
if (_showFps)
|
||||||
{
|
{
|
||||||
static int s_nRenderTimes = 0;
|
static int s_nRenderTimes = 0;
|
||||||
static double s_fLastRenderTime = 0;
|
static double s_fLastRenderTime = 0;
|
||||||
|
|
@ -267,11 +147,12 @@ void e2d::Renderer::__render()
|
||||||
}
|
}
|
||||||
|
|
||||||
IDWriteTextLayout * pTextLayout = nullptr;
|
IDWriteTextLayout * pTextLayout = nullptr;
|
||||||
|
IDWriteTextFormat * pTextFormat = Renderer::getFpsTextFormat();
|
||||||
|
|
||||||
hr = s_pDWriteFactory->CreateTextLayout(
|
hr = _writeFactory->CreateTextLayout(
|
||||||
(const WCHAR *)s_sFpsText,
|
(const WCHAR *)s_sFpsText,
|
||||||
(UINT32)s_sFpsText.getLength(),
|
(UINT32)s_sFpsText.getLength(),
|
||||||
s_pTextFormat,
|
pTextFormat,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
&pTextLayout
|
&pTextLayout
|
||||||
|
|
@ -279,9 +160,9 @@ void e2d::Renderer::__render()
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
s_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
|
_renderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
|
||||||
s_pSolidBrush->SetOpacity(1.0f);
|
_solidBrush->SetOpacity(1.0f);
|
||||||
s_pTextRenderer->SetTextStyle(
|
_textRenderer->SetTextStyle(
|
||||||
D2D1::ColorF(D2D1::ColorF::White),
|
D2D1::ColorF(D2D1::ColorF::White),
|
||||||
TRUE,
|
TRUE,
|
||||||
D2D1::ColorF(D2D1::ColorF::Black, 0.4f),
|
D2D1::ColorF(D2D1::ColorF::Black, 0.4f),
|
||||||
|
|
@ -289,21 +170,21 @@ void e2d::Renderer::__render()
|
||||||
D2D1_LINE_JOIN_ROUND
|
D2D1_LINE_JOIN_ROUND
|
||||||
);
|
);
|
||||||
|
|
||||||
pTextLayout->Draw(nullptr, s_pTextRenderer, 10, 0);
|
pTextLayout->Draw(nullptr, _textRenderer, 10, 0);
|
||||||
|
|
||||||
SafeRelease(pTextLayout);
|
SafeRelease(pTextLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 终止渲染
|
// 终止渲染
|
||||||
hr = s_pRenderTarget->EndDraw();
|
hr = _renderTarget->EndDraw();
|
||||||
|
|
||||||
if (hr == D2DERR_RECREATE_TARGET)
|
if (hr == D2DERR_RECREATE_TARGET)
|
||||||
{
|
{
|
||||||
// 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源
|
// 如果 Direct3D 设备在执行过程中消失,将丢弃当前的设备相关资源
|
||||||
// 并在下一次调用时重建资源
|
// 并在下一次调用时重建资源
|
||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
Renderer::__discardDeviceResources();
|
this->__discardDeviceResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
|
@ -312,73 +193,200 @@ void e2d::Renderer::__render()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
e2d::Color e2d::Renderer::getBackgroundColor()
|
e2d::Color e2d::Renderer::getBackgroundColor()
|
||||||
{
|
{
|
||||||
return Color(s_nClearColor.r, s_nClearColor.g, s_nClearColor.b, s_nClearColor.a);
|
return Color(_clearColor.r, _clearColor.g, _clearColor.b, _clearColor.a);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Renderer::setBackgroundColor(Color color)
|
void e2d::Renderer::setBackgroundColor(Color color)
|
||||||
{
|
{
|
||||||
s_nClearColor = color.toD2DColorF();
|
_clearColor = color.toD2DColorF();
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Renderer::showFps(bool show)
|
void e2d::Renderer::showFps(bool show)
|
||||||
{
|
{
|
||||||
s_bShowFps = show;
|
_showFps = show;
|
||||||
}
|
|
||||||
|
|
||||||
float e2d::Renderer::getDpiScaleX()
|
|
||||||
{
|
|
||||||
return s_fDpiScaleX;
|
|
||||||
}
|
|
||||||
|
|
||||||
float e2d::Renderer::getDpiScaleY()
|
|
||||||
{
|
|
||||||
return s_fDpiScaleY;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID2D1Factory * e2d::Renderer::getID2D1Factory()
|
|
||||||
{
|
|
||||||
return s_pDirect2dFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ID2D1HwndRenderTarget * e2d::Renderer::getRenderTarget()
|
ID2D1HwndRenderTarget * e2d::Renderer::getRenderTarget()
|
||||||
{
|
{
|
||||||
return s_pRenderTarget;
|
return _renderTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID2D1SolidColorBrush * e2d::Renderer::getSolidColorBrush()
|
ID2D1SolidColorBrush * e2d::Renderer::getSolidColorBrush()
|
||||||
{
|
{
|
||||||
return s_pSolidBrush;
|
return _solidBrush;
|
||||||
}
|
|
||||||
|
|
||||||
IWICImagingFactory * e2d::Renderer::getIWICImagingFactory()
|
|
||||||
{
|
|
||||||
return s_pIWICFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
IDWriteFactory * e2d::Renderer::getIDWriteFactory()
|
|
||||||
{
|
|
||||||
return s_pDWriteFactory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::TextRenderer * e2d::Renderer::getTextRenderer()
|
e2d::TextRenderer * e2d::Renderer::getTextRenderer()
|
||||||
{
|
{
|
||||||
return s_pTextRenderer;
|
if (!_textRenderer)
|
||||||
|
{
|
||||||
|
// 创建自定义的文字渲染器
|
||||||
|
_textRenderer = TextRenderer::Create(
|
||||||
|
Renderer::getFactory(),
|
||||||
|
this->getRenderTarget(),
|
||||||
|
this->getSolidColorBrush()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return _textRenderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID2D1StrokeStyle * e2d::Renderer::getMiterID2D1StrokeStyle()
|
ID2D1Factory * e2d::Renderer::getFactory()
|
||||||
{
|
{
|
||||||
return s_pMiterStrokeStyle;
|
if (!_d2dFactory)
|
||||||
|
{
|
||||||
|
HRESULT hr = D2D1CreateFactory(
|
||||||
|
D2D1_FACTORY_TYPE_SINGLE_THREADED,
|
||||||
|
&_d2dFactory
|
||||||
|
);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
throw SystemException(L"Create ID2D1Factory failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _d2dFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID2D1StrokeStyle * e2d::Renderer::getBevelID2D1StrokeStyle()
|
IWICImagingFactory * e2d::Renderer::getImagingFactory()
|
||||||
{
|
{
|
||||||
return s_pBevelStrokeStyle;
|
if (!_imagingFactory)
|
||||||
|
{
|
||||||
|
// 创建 WIC 绘图工厂,用于统一处理各种格式的图片
|
||||||
|
HRESULT hr = CoCreateInstance(
|
||||||
|
CLSID_WICImagingFactory,
|
||||||
|
nullptr,
|
||||||
|
CLSCTX_INPROC_SERVER,
|
||||||
|
IID_IWICImagingFactory,
|
||||||
|
reinterpret_cast<void**>(&_imagingFactory)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
throw SystemException(L"Create IWICImagingFactory failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _imagingFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
ID2D1StrokeStyle * e2d::Renderer::getRoundID2D1StrokeStyle()
|
IDWriteFactory * e2d::Renderer::getWriteFactory()
|
||||||
{
|
{
|
||||||
return s_pRoundStrokeStyle;
|
if (!_writeFactory)
|
||||||
|
{
|
||||||
|
// 创建 DirectWrite 工厂
|
||||||
|
HRESULT hr = DWriteCreateFactory(
|
||||||
|
DWRITE_FACTORY_TYPE_SHARED,
|
||||||
|
__uuidof(IDWriteFactory),
|
||||||
|
reinterpret_cast<IUnknown**>(&_writeFactory)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
throw SystemException(L"Create IDWriteFactory failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _writeFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
IDWriteTextFormat * e2d::Renderer::getFpsTextFormat()
|
||||||
|
{
|
||||||
|
if (!_textFormat)
|
||||||
|
{
|
||||||
|
// 创建 FPS 文本格式化对象
|
||||||
|
HRESULT hr = Renderer::getWriteFactory()->CreateTextFormat(
|
||||||
|
L"",
|
||||||
|
nullptr,
|
||||||
|
DWRITE_FONT_WEIGHT_NORMAL,
|
||||||
|
DWRITE_FONT_STYLE_NORMAL,
|
||||||
|
DWRITE_FONT_STRETCH_NORMAL,
|
||||||
|
20,
|
||||||
|
L"",
|
||||||
|
&_textFormat
|
||||||
|
);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
_textFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _textFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID2D1StrokeStyle * e2d::Renderer::getMiterStrokeStyle()
|
||||||
|
{
|
||||||
|
if (!_miterStrokeStyle)
|
||||||
|
{
|
||||||
|
HRESULT hr = Renderer::getFactory()->CreateStrokeStyle(
|
||||||
|
D2D1::StrokeStyleProperties(
|
||||||
|
D2D1_CAP_STYLE_FLAT,
|
||||||
|
D2D1_CAP_STYLE_FLAT,
|
||||||
|
D2D1_CAP_STYLE_FLAT,
|
||||||
|
D2D1_LINE_JOIN_MITER,
|
||||||
|
2.0f,
|
||||||
|
D2D1_DASH_STYLE_SOLID,
|
||||||
|
0.0f),
|
||||||
|
nullptr,
|
||||||
|
0,
|
||||||
|
&_miterStrokeStyle
|
||||||
|
);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
throw SystemException(L"Create ID2D1StrokeStyle failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _miterStrokeStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID2D1StrokeStyle * e2d::Renderer::getBevelStrokeStyle()
|
||||||
|
{
|
||||||
|
if (!_bevelStrokeStyle)
|
||||||
|
{
|
||||||
|
HRESULT hr = Renderer::getFactory()->CreateStrokeStyle(
|
||||||
|
D2D1::StrokeStyleProperties(
|
||||||
|
D2D1_CAP_STYLE_FLAT,
|
||||||
|
D2D1_CAP_STYLE_FLAT,
|
||||||
|
D2D1_CAP_STYLE_FLAT,
|
||||||
|
D2D1_LINE_JOIN_BEVEL,
|
||||||
|
2.0f,
|
||||||
|
D2D1_DASH_STYLE_SOLID,
|
||||||
|
0.0f),
|
||||||
|
nullptr,
|
||||||
|
0,
|
||||||
|
&_bevelStrokeStyle
|
||||||
|
);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
throw SystemException(L"Create ID2D1StrokeStyle failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _bevelStrokeStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
ID2D1StrokeStyle * e2d::Renderer::getRoundStrokeStyle()
|
||||||
|
{
|
||||||
|
if (!_roundStrokeStyle)
|
||||||
|
{
|
||||||
|
HRESULT hr = Renderer::getFactory()->CreateStrokeStyle(
|
||||||
|
D2D1::StrokeStyleProperties(
|
||||||
|
D2D1_CAP_STYLE_FLAT,
|
||||||
|
D2D1_CAP_STYLE_FLAT,
|
||||||
|
D2D1_CAP_STYLE_FLAT,
|
||||||
|
D2D1_LINE_JOIN_ROUND,
|
||||||
|
2.0f,
|
||||||
|
D2D1_DASH_STYLE_SOLID,
|
||||||
|
0.0f),
|
||||||
|
nullptr,
|
||||||
|
0,
|
||||||
|
&_roundStrokeStyle
|
||||||
|
);
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
throw SystemException(L"Create ID2D1StrokeStyle failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _roundStrokeStyle;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,48 @@
|
||||||
#include <imm.h>
|
#include <imm.h>
|
||||||
#pragma comment (lib ,"imm32.lib")
|
#pragma comment (lib ,"imm32.lib")
|
||||||
|
|
||||||
// 窗口句柄
|
|
||||||
static HWND s_HWnd = nullptr;
|
|
||||||
|
|
||||||
|
e2d::Window * e2d::Window::_instance = nullptr;
|
||||||
|
|
||||||
bool e2d::Window::__init()
|
e2d::Window::Window()
|
||||||
|
: _hWnd(nullptr)
|
||||||
|
, _size()
|
||||||
|
, _title()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
e2d::Window::~Window()
|
||||||
|
{
|
||||||
|
// 关闭控制台
|
||||||
|
if (::GetConsoleWindow())
|
||||||
|
{
|
||||||
|
::FreeConsole();
|
||||||
|
}
|
||||||
|
// 关闭窗口
|
||||||
|
if (_hWnd)
|
||||||
|
{
|
||||||
|
::DestroyWindow(_hWnd);
|
||||||
|
_hWnd = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
e2d::Window * e2d::Window::getInstance()
|
||||||
|
{
|
||||||
|
if (!_instance)
|
||||||
|
_instance = new (std::nothrow) Window;
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void e2d::Window::destroyInstance()
|
||||||
|
{
|
||||||
|
if (_instance)
|
||||||
|
{
|
||||||
|
delete _instance;
|
||||||
|
_instance = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool e2d::Window::create(const String& title, int width, int height)
|
||||||
{
|
{
|
||||||
// 注册窗口类
|
// 注册窗口类
|
||||||
WNDCLASSEX wcex = { 0 };
|
WNDCLASSEX wcex = { 0 };
|
||||||
|
|
@ -27,11 +64,11 @@ bool e2d::Window::__init()
|
||||||
|
|
||||||
// 因为 CreateWindow 函数使用的是像素大小,获取系统的 DPI 以使它
|
// 因为 CreateWindow 函数使用的是像素大小,获取系统的 DPI 以使它
|
||||||
// 适应窗口缩放
|
// 适应窗口缩放
|
||||||
float dpiX = Renderer::getDpiScaleX();
|
float dpiScaleX = 0.f, dpiScaleY = 0.f;
|
||||||
float dpiY = Renderer::getDpiScaleY();
|
Renderer::getFactory()->GetDesktopDpi(&dpiScaleX, &dpiScaleY);
|
||||||
|
|
||||||
int nWidth = static_cast<int>(ceil(640 * dpiX / 96.f));
|
int nWidth = static_cast<int>(ceil(width * dpiScaleX / 96.f));
|
||||||
int nHeight = static_cast<int>(ceil(480 * dpiY / 96.f));
|
int nHeight = static_cast<int>(ceil(height * dpiScaleY / 96.f));
|
||||||
|
|
||||||
// 计算窗口大小
|
// 计算窗口大小
|
||||||
DWORD dwStyle = WS_OVERLAPPEDWINDOW &~ WS_MAXIMIZEBOX &~ WS_THICKFRAME;
|
DWORD dwStyle = WS_OVERLAPPEDWINDOW &~ WS_MAXIMIZEBOX &~ WS_THICKFRAME;
|
||||||
|
|
@ -46,10 +83,10 @@ bool e2d::Window::__init()
|
||||||
int screenHeight = ::GetSystemMetrics(SM_CYSCREEN);
|
int screenHeight = ::GetSystemMetrics(SM_CYSCREEN);
|
||||||
|
|
||||||
// 创建窗口
|
// 创建窗口
|
||||||
s_HWnd = ::CreateWindowEx(
|
_hWnd = ::CreateWindowEx(
|
||||||
NULL,
|
NULL,
|
||||||
L"Easy2DApp",
|
L"Easy2DApp",
|
||||||
L"Easy2D Game",
|
(LPCTSTR)title,
|
||||||
dwStyle,
|
dwStyle,
|
||||||
(screenWidth - nWidth) / 2, (screenHeight - nHeight) / 2,
|
(screenWidth - nWidth) / 2, (screenHeight - nHeight) / 2,
|
||||||
nWidth, nHeight,
|
nWidth, nHeight,
|
||||||
|
|
@ -59,12 +96,12 @@ bool e2d::Window::__init()
|
||||||
nullptr
|
nullptr
|
||||||
);
|
);
|
||||||
|
|
||||||
HRESULT hr = s_HWnd ? S_OK : E_FAIL;
|
HRESULT hr = _hWnd ? S_OK : E_FAIL;
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
// 禁用输入法
|
// 禁用输入法
|
||||||
Window::setTypewritingEnable(false);
|
this->setTypewritingEnable(false);
|
||||||
// 禁用控制台关闭按钮
|
// 禁用控制台关闭按钮
|
||||||
HWND consoleHWnd = ::GetConsoleWindow();
|
HWND consoleHWnd = ::GetConsoleWindow();
|
||||||
if (consoleHWnd)
|
if (consoleHWnd)
|
||||||
|
|
@ -72,32 +109,15 @@ bool e2d::Window::__init()
|
||||||
HMENU hmenu = ::GetSystemMenu(consoleHWnd, FALSE);
|
HMENU hmenu = ::GetSystemMenu(consoleHWnd, FALSE);
|
||||||
::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND);
|
::RemoveMenu(hmenu, SC_CLOSE, MF_BYCOMMAND);
|
||||||
}
|
}
|
||||||
|
this->_size = Size(width, height);
|
||||||
|
this->_title = title;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
::UnregisterClass(L"Easy2DApp", HINST_THISCOMPONENT);
|
::UnregisterClass(L"Easy2DApp", HINST_THISCOMPONENT);
|
||||||
}
|
this->error(L"Create Window Failed!");
|
||||||
|
return false;
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
|
||||||
Window::error(L"Create Window Failed!");
|
|
||||||
}
|
|
||||||
|
|
||||||
return SUCCEEDED(hr);
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::Window::__uninit()
|
|
||||||
{
|
|
||||||
// 关闭控制台
|
|
||||||
if (::GetConsoleWindow())
|
|
||||||
{
|
|
||||||
::FreeConsole();
|
|
||||||
}
|
|
||||||
// 关闭窗口
|
|
||||||
if (s_HWnd)
|
|
||||||
{
|
|
||||||
::DestroyWindow(s_HWnd);
|
|
||||||
s_HWnd = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,43 +134,27 @@ void e2d::Window::__poll()
|
||||||
|
|
||||||
double e2d::Window::getWidth()
|
double e2d::Window::getWidth()
|
||||||
{
|
{
|
||||||
if (s_HWnd)
|
return _size.width;
|
||||||
{
|
|
||||||
// 获取客户区大小
|
|
||||||
tagRECT rcClient;
|
|
||||||
::GetClientRect(s_HWnd, &rcClient);
|
|
||||||
return rcClient.right - rcClient.left;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double e2d::Window::getHeight()
|
double e2d::Window::getHeight()
|
||||||
{
|
{
|
||||||
if (s_HWnd)
|
return _size.height;
|
||||||
{
|
|
||||||
// 获取客户区大小
|
|
||||||
tagRECT rcClient;
|
|
||||||
::GetClientRect(s_HWnd, &rcClient);
|
|
||||||
return rcClient.bottom - rcClient.top;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::Size e2d::Window::getSize()
|
e2d::Size e2d::Window::getSize()
|
||||||
{
|
{
|
||||||
if (s_HWnd)
|
return _size;
|
||||||
{
|
}
|
||||||
// 获取客户区大小
|
|
||||||
tagRECT rcClient;
|
e2d::String e2d::Window::getTitle()
|
||||||
::GetClientRect(s_HWnd, &rcClient);
|
{
|
||||||
return Size(rcClient.right - rcClient.left, rcClient.bottom - rcClient.top);
|
return _title;
|
||||||
}
|
|
||||||
return Size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HWND e2d::Window::getHWnd()
|
HWND e2d::Window::getHWnd()
|
||||||
{
|
{
|
||||||
return s_HWnd;
|
return _hWnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Window::setSize(int width, int height)
|
void e2d::Window::setSize(int width, int height)
|
||||||
|
|
@ -171,13 +175,13 @@ void e2d::Window::setSize(int width, int height)
|
||||||
width = min(width, screenWidth);
|
width = min(width, screenWidth);
|
||||||
height = min(height, screenHeight);
|
height = min(height, screenHeight);
|
||||||
// 修改窗口大小,并设置窗口在屏幕居中
|
// 修改窗口大小,并设置窗口在屏幕居中
|
||||||
::MoveWindow(s_HWnd, (screenWidth - width) / 2, (screenHeight - height) / 2, width, height, TRUE);
|
::MoveWindow(_hWnd, (screenWidth - width) / 2, (screenHeight - height) / 2, width, height, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Window::setTitle(const String& title)
|
void e2d::Window::setTitle(const String& title)
|
||||||
{
|
{
|
||||||
// 设置窗口标题
|
// 设置窗口标题
|
||||||
::SetWindowText(s_HWnd, (LPCWSTR)title);
|
::SetWindowText(_hWnd, (LPCWSTR)title);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Window::setIcon(int iconID)
|
void e2d::Window::setIcon(int iconID)
|
||||||
|
|
@ -185,8 +189,8 @@ void e2d::Window::setIcon(int iconID)
|
||||||
HINSTANCE hInstance = ::GetModuleHandle(nullptr);
|
HINSTANCE hInstance = ::GetModuleHandle(nullptr);
|
||||||
HICON hIcon = (HICON)::LoadImage(hInstance, MAKEINTRESOURCE(iconID), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
|
HICON hIcon = (HICON)::LoadImage(hInstance, MAKEINTRESOURCE(iconID), IMAGE_ICON, 0, 0, LR_DEFAULTCOLOR | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
|
||||||
// 设置窗口的图标
|
// 设置窗口的图标
|
||||||
::SendMessage(s_HWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
::SendMessage(_hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
|
||||||
::SendMessage(s_HWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
::SendMessage(_hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Window::setCursor(Cursor cursor)
|
void e2d::Window::setCursor(Cursor cursor)
|
||||||
|
|
@ -222,13 +226,6 @@ void e2d::Window::setCursor(Cursor cursor)
|
||||||
::SetCursor(hCursor);
|
::SetCursor(hCursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
e2d::String e2d::Window::getTitle()
|
|
||||||
{
|
|
||||||
wchar_t wszTitle[MAX_PATH] = { 0 };
|
|
||||||
::GetWindowText(s_HWnd, wszTitle, MAX_PATH);
|
|
||||||
return wszTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
void e2d::Window::showConsole(bool show)
|
void e2d::Window::showConsole(bool show)
|
||||||
{
|
{
|
||||||
// 查找已存在的控制台句柄
|
// 查找已存在的控制台句柄
|
||||||
|
|
@ -257,7 +254,7 @@ void e2d::Window::showConsole(bool show)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Window::error(L"Alloc Console Failed!");
|
this->error(L"Alloc Console Failed!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -278,7 +275,7 @@ void e2d::Window::setTypewritingEnable(bool enable)
|
||||||
{
|
{
|
||||||
if (hImc != nullptr)
|
if (hImc != nullptr)
|
||||||
{
|
{
|
||||||
::ImmAssociateContext(Window::getHWnd(), hImc);
|
::ImmAssociateContext(_hWnd, hImc);
|
||||||
hImc = nullptr;
|
hImc = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -286,26 +283,26 @@ void e2d::Window::setTypewritingEnable(bool enable)
|
||||||
{
|
{
|
||||||
if (hImc == nullptr)
|
if (hImc == nullptr)
|
||||||
{
|
{
|
||||||
hImc = ::ImmAssociateContext(Window::getHWnd(), nullptr);
|
hImc = ::ImmAssociateContext(_hWnd, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Window::info(const String & text, const String & title)
|
void e2d::Window::info(const String & text, const String & title)
|
||||||
{
|
{
|
||||||
::MessageBox(s_HWnd, (LPCWSTR)text, (LPCWSTR)title, MB_ICONINFORMATION | MB_OK);
|
::MessageBox(_hWnd, (LPCWSTR)text, (LPCWSTR)title, MB_ICONINFORMATION | MB_OK);
|
||||||
Game::getInstance()->reset();
|
Game::getInstance()->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Window::warning(const String& title, const String& text)
|
void e2d::Window::warning(const String& title, const String& text)
|
||||||
{
|
{
|
||||||
::MessageBox(s_HWnd, (LPCWSTR)text, (LPCWSTR)title, MB_ICONWARNING | MB_OK);
|
::MessageBox(_hWnd, (LPCWSTR)text, (LPCWSTR)title, MB_ICONWARNING | MB_OK);
|
||||||
Game::getInstance()->reset();
|
Game::getInstance()->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Window::error(const String & text, const String & title)
|
void e2d::Window::error(const String & text, const String & title)
|
||||||
{
|
{
|
||||||
::MessageBox(s_HWnd, (LPCWSTR)text, (LPCWSTR)title, MB_ICONERROR | MB_OK);
|
::MessageBox(_hWnd, (LPCWSTR)text, (LPCWSTR)title, MB_ICONERROR | MB_OK);
|
||||||
Game::getInstance()->reset();
|
Game::getInstance()->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -323,11 +320,25 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
|
||||||
{
|
{
|
||||||
UINT width = LOWORD(lParam);
|
UINT width = LOWORD(lParam);
|
||||||
UINT height = HIWORD(lParam);
|
UINT height = HIWORD(lParam);
|
||||||
|
|
||||||
|
auto instance = Window::getInstance();
|
||||||
|
if (instance)
|
||||||
|
instance->_size = Size(width, height);
|
||||||
|
|
||||||
// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染
|
// 如果程序接收到一个 WM_SIZE 消息,这个方法将调整渲染
|
||||||
// 目标适当。它可能会调用失败,但是这里可以忽略有可能的
|
// 目标适当。它可能会调用失败,但是这里可以忽略有可能的
|
||||||
// 错误,因为这个错误将在下一次调用 EndDraw 时产生
|
// 错误,因为这个错误将在下一次调用 EndDraw 时产生
|
||||||
auto pRT = Renderer::getRenderTarget();
|
auto pRT = Renderer::getInstance()->getRenderTarget();
|
||||||
if (pRT) pRT->Resize(D2D1::SizeU(width, height));
|
if (pRT)
|
||||||
|
pRT->Resize(D2D1::SizeU(width, height));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// 处理窗口标题变化消息
|
||||||
|
case WM_SETTEXT:
|
||||||
|
{
|
||||||
|
auto instance = Window::getInstance();
|
||||||
|
instance->_title = (const wchar_t*)lParam;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -344,7 +355,7 @@ LRESULT e2d::Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPar
|
||||||
// 重绘窗口
|
// 重绘窗口
|
||||||
case WM_PAINT:
|
case WM_PAINT:
|
||||||
{
|
{
|
||||||
e2d::Renderer::__render();
|
e2d::Renderer::getInstance()->__render();
|
||||||
ValidateRect(hWnd, nullptr);
|
ValidateRect(hWnd, nullptr);
|
||||||
}
|
}
|
||||||
result = 0;
|
result = 0;
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ void e2d::CircleCollider::setCircle(Point center, double radius)
|
||||||
{
|
{
|
||||||
SafeRelease(_d2dCircle);
|
SafeRelease(_d2dCircle);
|
||||||
|
|
||||||
Renderer::getID2D1Factory()->CreateEllipseGeometry(
|
Renderer::getFactory()->CreateEllipseGeometry(
|
||||||
D2D1::Ellipse(
|
D2D1::Ellipse(
|
||||||
D2D1::Point2F(
|
D2D1::Point2F(
|
||||||
float(center.x),
|
float(center.x),
|
||||||
|
|
|
||||||
|
|
@ -51,12 +51,13 @@ void e2d::Collider::_render()
|
||||||
{
|
{
|
||||||
if (_transformed && _enable)
|
if (_transformed && _enable)
|
||||||
{
|
{
|
||||||
|
auto renderer = Renderer::getInstance();
|
||||||
// 获取纯色画刷
|
// 获取纯色画刷
|
||||||
ID2D1SolidColorBrush * pBrush = Renderer::getSolidColorBrush();
|
ID2D1SolidColorBrush * pBrush = renderer->getSolidColorBrush();
|
||||||
// 设置画刷颜色和透明度
|
// 设置画刷颜色和透明度
|
||||||
pBrush->SetColor(_color.toD2DColorF());
|
pBrush->SetColor(_color.toD2DColorF());
|
||||||
// 绘制几何碰撞体
|
// 绘制几何碰撞体
|
||||||
Renderer::getRenderTarget()->DrawGeometry(_transformed, pBrush);
|
renderer->getRenderTarget()->DrawGeometry(_transformed, pBrush);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,7 +94,7 @@ void e2d::Collider::_transform()
|
||||||
SafeRelease(_transformed);
|
SafeRelease(_transformed);
|
||||||
|
|
||||||
// 根据父节点转换几何图形
|
// 根据父节点转换几何图形
|
||||||
Renderer::getID2D1Factory()->CreateTransformedGeometry(
|
Renderer::getFactory()->CreateTransformedGeometry(
|
||||||
getD2dGeometry(),
|
getD2dGeometry(),
|
||||||
_parentNode->_finalMatri,
|
_parentNode->_finalMatri,
|
||||||
&_transformed
|
&_transformed
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ void e2d::EllipseCollider::setEllipse(Point center, double radiusX, double radiu
|
||||||
{
|
{
|
||||||
SafeRelease(_d2dEllipse);
|
SafeRelease(_d2dEllipse);
|
||||||
|
|
||||||
Renderer::getID2D1Factory()->CreateEllipseGeometry(
|
Renderer::getFactory()->CreateEllipseGeometry(
|
||||||
D2D1::Ellipse(
|
D2D1::Ellipse(
|
||||||
D2D1::Point2F(
|
D2D1::Point2F(
|
||||||
float(center.x),
|
float(center.x),
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ void e2d::RectCollider::setRect(double left, double top, double right, double bo
|
||||||
{
|
{
|
||||||
SafeRelease(_d2dRectangle);
|
SafeRelease(_d2dRectangle);
|
||||||
|
|
||||||
Renderer::getID2D1Factory()->CreateRectangleGeometry(
|
Renderer::getFactory()->CreateRectangleGeometry(
|
||||||
D2D1::RectF(
|
D2D1::RectF(
|
||||||
float(left),
|
float(left),
|
||||||
float(top),
|
float(top),
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ bool e2d::Image::preload(const String& filePath)
|
||||||
ID2D1Bitmap *pBitmap = nullptr;
|
ID2D1Bitmap *pBitmap = nullptr;
|
||||||
|
|
||||||
// 创建解码器
|
// 创建解码器
|
||||||
hr = Renderer::getIWICImagingFactory()->CreateDecoderFromFilename(
|
hr = Renderer::getImagingFactory()->CreateDecoderFromFilename(
|
||||||
(LPCWSTR)actualFilePath,
|
(LPCWSTR)actualFilePath,
|
||||||
nullptr,
|
nullptr,
|
||||||
GENERIC_READ,
|
GENERIC_READ,
|
||||||
|
|
@ -194,7 +194,7 @@ bool e2d::Image::preload(const String& filePath)
|
||||||
{
|
{
|
||||||
// 创建图片格式转换器
|
// 创建图片格式转换器
|
||||||
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
|
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
|
||||||
hr = Renderer::getIWICImagingFactory()->CreateFormatConverter(&pConverter);
|
hr = Renderer::getImagingFactory()->CreateFormatConverter(&pConverter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
|
|
@ -213,7 +213,7 @@ bool e2d::Image::preload(const String& filePath)
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
// 从 WIC 位图创建一个 Direct2D 位图
|
// 从 WIC 位图创建一个 Direct2D 位图
|
||||||
hr = Renderer::getRenderTarget()->CreateBitmapFromWicBitmap(
|
hr = Renderer::getInstance()->getRenderTarget()->CreateBitmapFromWicBitmap(
|
||||||
pConverter,
|
pConverter,
|
||||||
nullptr,
|
nullptr,
|
||||||
&pBitmap
|
&pBitmap
|
||||||
|
|
@ -291,7 +291,7 @@ bool e2d::Image::preload(int resNameId, const String& resType)
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
// 创建 WIC 流
|
// 创建 WIC 流
|
||||||
hr = Renderer::getIWICImagingFactory()->CreateStream(&pStream);
|
hr = Renderer::getImagingFactory()->CreateStream(&pStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
|
|
@ -306,7 +306,7 @@ bool e2d::Image::preload(int resNameId, const String& resType)
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
// 创建流的解码器
|
// 创建流的解码器
|
||||||
hr = Renderer::getIWICImagingFactory()->CreateDecoderFromStream(
|
hr = Renderer::getImagingFactory()->CreateDecoderFromStream(
|
||||||
pStream,
|
pStream,
|
||||||
nullptr,
|
nullptr,
|
||||||
WICDecodeMetadataCacheOnLoad,
|
WICDecodeMetadataCacheOnLoad,
|
||||||
|
|
@ -324,7 +324,7 @@ bool e2d::Image::preload(int resNameId, const String& resType)
|
||||||
{
|
{
|
||||||
// 创建图片格式转换器
|
// 创建图片格式转换器
|
||||||
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
|
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
|
||||||
hr = Renderer::getIWICImagingFactory()->CreateFormatConverter(&pConverter);
|
hr = Renderer::getImagingFactory()->CreateFormatConverter(&pConverter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
|
|
@ -343,7 +343,7 @@ bool e2d::Image::preload(int resNameId, const String& resType)
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
// 从 WIC 位图创建一个 Direct2D 位图
|
// 从 WIC 位图创建一个 Direct2D 位图
|
||||||
hr = Renderer::getRenderTarget()->CreateBitmapFromWicBitmap(
|
hr = Renderer::getInstance()->getRenderTarget()->CreateBitmapFromWicBitmap(
|
||||||
pConverter,
|
pConverter,
|
||||||
nullptr,
|
nullptr,
|
||||||
&pBitmap
|
&pBitmap
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ e2d::Object::~Object()
|
||||||
|
|
||||||
void e2d::Object::autorelease()
|
void e2d::Object::autorelease()
|
||||||
{
|
{
|
||||||
GC::__add(this);
|
GC::getInstance()->addObject(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void e2d::Object::retain()
|
void e2d::Object::retain()
|
||||||
|
|
@ -24,7 +24,7 @@ void e2d::Object::retain()
|
||||||
void e2d::Object::release()
|
void e2d::Object::release()
|
||||||
{
|
{
|
||||||
_refCount--;
|
_refCount--;
|
||||||
GC::notify();
|
GC::getInstance()->notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
int e2d::Object::getRefCount() const
|
int e2d::Object::getRefCount() const
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ void e2d::Scene::_render()
|
||||||
if (_colliderVisiable)
|
if (_colliderVisiable)
|
||||||
{
|
{
|
||||||
// 恢复矩阵转换
|
// 恢复矩阵转换
|
||||||
Renderer::getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
|
Renderer::getInstance()->getRenderTarget()->SetTransform(D2D1::Matrix3x2F::Identity());
|
||||||
// 绘制所有几何图形
|
// 绘制所有几何图形
|
||||||
_root->_drawCollider();
|
_root->_drawCollider();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,13 +59,13 @@ STDMETHODIMP_(void) TextRenderer::SetTextStyle(
|
||||||
switch (outlineJoin)
|
switch (outlineJoin)
|
||||||
{
|
{
|
||||||
case D2D1_LINE_JOIN_MITER:
|
case D2D1_LINE_JOIN_MITER:
|
||||||
pCurrStrokeStyle_ = Renderer::getMiterID2D1StrokeStyle();
|
pCurrStrokeStyle_ = Renderer::getMiterStrokeStyle();
|
||||||
break;
|
break;
|
||||||
case D2D1_LINE_JOIN_BEVEL:
|
case D2D1_LINE_JOIN_BEVEL:
|
||||||
pCurrStrokeStyle_ = Renderer::getBevelID2D1StrokeStyle();
|
pCurrStrokeStyle_ = Renderer::getBevelStrokeStyle();
|
||||||
break;
|
break;
|
||||||
case D2D1_LINE_JOIN_ROUND:
|
case D2D1_LINE_JOIN_ROUND:
|
||||||
pCurrStrokeStyle_ = Renderer::getRoundID2D1StrokeStyle();
|
pCurrStrokeStyle_ = Renderer::getRoundStrokeStyle();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pCurrStrokeStyle_ = nullptr;
|
pCurrStrokeStyle_ = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -209,14 +209,14 @@ void e2d::Button::_fixedUpdate()
|
||||||
if (_normal->containsPoint(Input::getMousePos()))
|
if (_normal->containsPoint(Input::getMousePos()))
|
||||||
{
|
{
|
||||||
_setState(ButtonState::Selected);
|
_setState(ButtonState::Selected);
|
||||||
Window::setCursor(Window::Cursor::Hand);
|
Window::getInstance()->setCursor(Window::Cursor::Hand);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (_normal->containsPoint(Input::getMousePos()))
|
else if (_normal->containsPoint(Input::getMousePos()))
|
||||||
{
|
{
|
||||||
_setState(ButtonState::Mouseover);
|
_setState(ButtonState::Mouseover);
|
||||||
Window::setCursor(Window::Cursor::Hand);
|
Window::getInstance()->setCursor(Window::Cursor::Hand);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -225,7 +225,7 @@ void e2d::Button::_fixedUpdate()
|
||||||
|
|
||||||
if (_visiable && !_enable && _normal && _normal->containsPoint(Input::getMousePos()))
|
if (_visiable && !_enable && _normal && _normal->containsPoint(Input::getMousePos()))
|
||||||
{
|
{
|
||||||
Window::setCursor(Window::Cursor::No);
|
Window::getInstance()->setCursor(Window::Cursor::No);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ void e2d::Node::_render()
|
||||||
if (_children.empty())
|
if (_children.empty())
|
||||||
{
|
{
|
||||||
// 转换渲染器的二维矩阵
|
// 转换渲染器的二维矩阵
|
||||||
Renderer::getRenderTarget()->SetTransform(_finalMatri);
|
Renderer::getInstance()->getRenderTarget()->SetTransform(_finalMatri);
|
||||||
// 渲染自身
|
// 渲染自身
|
||||||
this->onRender();
|
this->onRender();
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +131,7 @@ void e2d::Node::_render()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 转换渲染器的二维矩阵
|
// 转换渲染器的二维矩阵
|
||||||
Renderer::getRenderTarget()->SetTransform(_finalMatri);
|
Renderer::getInstance()->getRenderTarget()->SetTransform(_finalMatri);
|
||||||
// 渲染自身
|
// 渲染自身
|
||||||
this->onRender();
|
this->onRender();
|
||||||
|
|
||||||
|
|
@ -826,7 +826,7 @@ bool e2d::Node::containsPoint(const Point& point) const
|
||||||
{
|
{
|
||||||
// 为节点创建一个临时碰撞体
|
// 为节点创建一个临时碰撞体
|
||||||
ID2D1RectangleGeometry * rect;
|
ID2D1RectangleGeometry * rect;
|
||||||
Renderer::getID2D1Factory()->CreateRectangleGeometry(
|
Renderer::getFactory()->CreateRectangleGeometry(
|
||||||
D2D1::RectF(0, 0, _width, _height),
|
D2D1::RectF(0, 0, _width, _height),
|
||||||
&rect
|
&rect
|
||||||
);
|
);
|
||||||
|
|
@ -871,18 +871,18 @@ bool e2d::Node::intersects(Node * node) const
|
||||||
D2D1_GEOMETRY_RELATION relation;
|
D2D1_GEOMETRY_RELATION relation;
|
||||||
|
|
||||||
// 根据自身大小位置创建矩形
|
// 根据自身大小位置创建矩形
|
||||||
Renderer::getID2D1Factory()->CreateRectangleGeometry(
|
Renderer::getFactory()->CreateRectangleGeometry(
|
||||||
D2D1::RectF(0, 0, _width, _height),
|
D2D1::RectF(0, 0, _width, _height),
|
||||||
&pRect1
|
&pRect1
|
||||||
);
|
);
|
||||||
// 根据二维矩阵进行转换
|
// 根据二维矩阵进行转换
|
||||||
Renderer::getID2D1Factory()->CreateTransformedGeometry(
|
Renderer::getFactory()->CreateTransformedGeometry(
|
||||||
pRect1,
|
pRect1,
|
||||||
_finalMatri,
|
_finalMatri,
|
||||||
&pCollider
|
&pCollider
|
||||||
);
|
);
|
||||||
// 根据相比较节点的大小位置创建矩形
|
// 根据相比较节点的大小位置创建矩形
|
||||||
Renderer::getID2D1Factory()->CreateRectangleGeometry(
|
Renderer::getFactory()->CreateRectangleGeometry(
|
||||||
D2D1::RectF(0, 0, node->_width, node->_height),
|
D2D1::RectF(0, 0, node->_width, node->_height),
|
||||||
&pRect2
|
&pRect2
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,10 @@ void e2d::CircleShape::setRadius(double radius)
|
||||||
|
|
||||||
void e2d::CircleShape::_renderLine()
|
void e2d::CircleShape::_renderLine()
|
||||||
{
|
{
|
||||||
Renderer::getRenderTarget()->DrawEllipse(
|
auto renderer = Renderer::getInstance();
|
||||||
|
renderer->getRenderTarget()->DrawEllipse(
|
||||||
D2D1::Ellipse(D2D1::Point2F(_radius, _radius), _radius, _radius),
|
D2D1::Ellipse(D2D1::Point2F(_radius, _radius), _radius, _radius),
|
||||||
Renderer::getSolidColorBrush(),
|
renderer->getSolidColorBrush(),
|
||||||
_strokeWidth,
|
_strokeWidth,
|
||||||
_strokeStyle
|
_strokeStyle
|
||||||
);
|
);
|
||||||
|
|
@ -46,8 +47,9 @@ void e2d::CircleShape::_renderLine()
|
||||||
|
|
||||||
void e2d::CircleShape::_renderFill()
|
void e2d::CircleShape::_renderFill()
|
||||||
{
|
{
|
||||||
Renderer::getRenderTarget()->FillEllipse(
|
auto renderer = Renderer::getInstance();
|
||||||
|
renderer->getRenderTarget()->FillEllipse(
|
||||||
D2D1::Ellipse(D2D1::Point2F(_radius, _radius), _radius, _radius),
|
D2D1::Ellipse(D2D1::Point2F(_radius, _radius), _radius, _radius),
|
||||||
Renderer::getSolidColorBrush()
|
renderer->getSolidColorBrush()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,10 @@ void e2d::EllipseShape::setRadiusY(double radiusY)
|
||||||
|
|
||||||
void e2d::EllipseShape::_renderLine()
|
void e2d::EllipseShape::_renderLine()
|
||||||
{
|
{
|
||||||
Renderer::getRenderTarget()->DrawEllipse(
|
auto renderer = Renderer::getInstance();
|
||||||
|
renderer->getRenderTarget()->DrawEllipse(
|
||||||
D2D1::Ellipse(D2D1::Point2F(_radiusX, _radiusY), _radiusX, _radiusY),
|
D2D1::Ellipse(D2D1::Point2F(_radiusX, _radiusY), _radiusX, _radiusY),
|
||||||
Renderer::getSolidColorBrush(),
|
renderer->getSolidColorBrush(),
|
||||||
_strokeWidth,
|
_strokeWidth,
|
||||||
_strokeStyle
|
_strokeStyle
|
||||||
);
|
);
|
||||||
|
|
@ -60,8 +61,9 @@ void e2d::EllipseShape::_renderLine()
|
||||||
|
|
||||||
void e2d::EllipseShape::_renderFill()
|
void e2d::EllipseShape::_renderFill()
|
||||||
{
|
{
|
||||||
Renderer::getRenderTarget()->FillEllipse(
|
auto renderer = Renderer::getInstance();
|
||||||
|
renderer->getRenderTarget()->FillEllipse(
|
||||||
D2D1::Ellipse(D2D1::Point2F(_radiusX, _radiusY), _radiusX, _radiusY),
|
D2D1::Ellipse(D2D1::Point2F(_radiusX, _radiusY), _radiusX, _radiusY),
|
||||||
Renderer::getSolidColorBrush()
|
renderer->getSolidColorBrush()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,10 @@ e2d::RectShape::~RectShape()
|
||||||
|
|
||||||
void e2d::RectShape::_renderLine()
|
void e2d::RectShape::_renderLine()
|
||||||
{
|
{
|
||||||
Renderer::getRenderTarget()->DrawRectangle(
|
auto renderer = Renderer::getInstance();
|
||||||
|
renderer->getRenderTarget()->DrawRectangle(
|
||||||
D2D1::RectF(0, 0, _width, _height),
|
D2D1::RectF(0, 0, _width, _height),
|
||||||
Renderer::getSolidColorBrush(),
|
renderer->getSolidColorBrush(),
|
||||||
_strokeWidth,
|
_strokeWidth,
|
||||||
_strokeStyle
|
_strokeStyle
|
||||||
);
|
);
|
||||||
|
|
@ -32,8 +33,9 @@ void e2d::RectShape::_renderLine()
|
||||||
|
|
||||||
void e2d::RectShape::_renderFill()
|
void e2d::RectShape::_renderFill()
|
||||||
{
|
{
|
||||||
Renderer::getRenderTarget()->FillRectangle(
|
auto renderer = Renderer::getInstance();
|
||||||
|
renderer->getRenderTarget()->FillRectangle(
|
||||||
D2D1::RectF(0, 0, _width, _height),
|
D2D1::RectF(0, 0, _width, _height),
|
||||||
Renderer::getSolidColorBrush()
|
renderer->getSolidColorBrush()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,9 +48,10 @@ void e2d::RoundRectShape::setRadiusY(double radiusY)
|
||||||
|
|
||||||
void e2d::RoundRectShape::_renderLine()
|
void e2d::RoundRectShape::_renderLine()
|
||||||
{
|
{
|
||||||
Renderer::getRenderTarget()->DrawRoundedRectangle(
|
auto renderer = Renderer::getInstance();
|
||||||
|
renderer->getRenderTarget()->DrawRoundedRectangle(
|
||||||
D2D1::RoundedRect(D2D1::RectF(0, 0, _width, _height), _radiusX, _radiusY),
|
D2D1::RoundedRect(D2D1::RectF(0, 0, _width, _height), _radiusX, _radiusY),
|
||||||
Renderer::getSolidColorBrush(),
|
renderer->getSolidColorBrush(),
|
||||||
_strokeWidth,
|
_strokeWidth,
|
||||||
_strokeStyle
|
_strokeStyle
|
||||||
);
|
);
|
||||||
|
|
@ -58,8 +59,9 @@ void e2d::RoundRectShape::_renderLine()
|
||||||
|
|
||||||
void e2d::RoundRectShape::_renderFill()
|
void e2d::RoundRectShape::_renderFill()
|
||||||
{
|
{
|
||||||
Renderer::getRenderTarget()->FillRoundedRectangle(
|
auto renderer = Renderer::getInstance();
|
||||||
|
renderer->getRenderTarget()->FillRoundedRectangle(
|
||||||
D2D1::RoundedRect(D2D1::RectF(0, 0, _width, _height), _radiusX, _radiusY),
|
D2D1::RoundedRect(D2D1::RectF(0, 0, _width, _height), _radiusX, _radiusY),
|
||||||
Renderer::getSolidColorBrush()
|
renderer->getSolidColorBrush()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ e2d::Shape::~Shape()
|
||||||
|
|
||||||
void e2d::Shape::onRender()
|
void e2d::Shape::onRender()
|
||||||
{
|
{
|
||||||
auto pBrush = Renderer::getSolidColorBrush();
|
auto pBrush = Renderer::getInstance()->getSolidColorBrush();
|
||||||
pBrush->SetOpacity(_displayOpacity);
|
pBrush->SetOpacity(_displayOpacity);
|
||||||
|
|
||||||
switch (_style)
|
switch (_style)
|
||||||
|
|
@ -94,13 +94,13 @@ void e2d::Shape::setLineJoin(LineJoin lineJoin)
|
||||||
switch (lineJoin)
|
switch (lineJoin)
|
||||||
{
|
{
|
||||||
case LineJoin::Miter:
|
case LineJoin::Miter:
|
||||||
_strokeStyle = Renderer::getMiterID2D1StrokeStyle();
|
_strokeStyle = Renderer::getMiterStrokeStyle();
|
||||||
break;
|
break;
|
||||||
case LineJoin::Bevel:
|
case LineJoin::Bevel:
|
||||||
_strokeStyle = Renderer::getBevelID2D1StrokeStyle();
|
_strokeStyle = Renderer::getBevelStrokeStyle();
|
||||||
break;
|
break;
|
||||||
case LineJoin::Round:
|
case LineJoin::Round:
|
||||||
_strokeStyle = Renderer::getRoundID2D1StrokeStyle();
|
_strokeStyle = Renderer::getRoundStrokeStyle();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
_strokeStyle = nullptr;
|
_strokeStyle = nullptr;
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ void e2d::Sprite::onRender()
|
||||||
float fCropX = float(_image->getCropX());
|
float fCropX = float(_image->getCropX());
|
||||||
float fCropY = float(_image->getCropY());
|
float fCropY = float(_image->getCropY());
|
||||||
// äÖȾͼƬ
|
// äÖȾͼƬ
|
||||||
Renderer::getRenderTarget()->DrawBitmap(
|
Renderer::getInstance()->getRenderTarget()->DrawBitmap(
|
||||||
_image->getBitmap(),
|
_image->getBitmap(),
|
||||||
D2D1::RectF(0, 0, _width, _height),
|
D2D1::RectF(0, 0, _width, _height),
|
||||||
_displayOpacity,
|
_displayOpacity,
|
||||||
|
|
|
||||||
|
|
@ -291,12 +291,13 @@ void e2d::Text::onRender()
|
||||||
{
|
{
|
||||||
if (_textLayout)
|
if (_textLayout)
|
||||||
{
|
{
|
||||||
|
auto renderer = Renderer::getInstance();
|
||||||
// 创建文本区域
|
// 创建文本区域
|
||||||
D2D1_RECT_F textLayoutRect = D2D1::RectF(0, 0, _width, _height);
|
D2D1_RECT_F textLayoutRect = D2D1::RectF(0, 0, _width, _height);
|
||||||
// 设置画刷颜色和透明度
|
// 设置画刷颜色和透明度
|
||||||
Renderer::getSolidColorBrush()->SetOpacity(_displayOpacity);
|
renderer->getSolidColorBrush()->SetOpacity(_displayOpacity);
|
||||||
// 获取文本渲染器
|
// 获取文本渲染器
|
||||||
auto pTextRenderer = Renderer::getTextRenderer();
|
auto pTextRenderer = renderer->getTextRenderer();
|
||||||
pTextRenderer->SetTextStyle(
|
pTextRenderer->SetTextStyle(
|
||||||
_style.color.toD2DColorF(),
|
_style.color.toD2DColorF(),
|
||||||
_style.hasOutline,
|
_style.hasOutline,
|
||||||
|
|
@ -320,7 +321,7 @@ void e2d::Text::_createFormat()
|
||||||
{
|
{
|
||||||
SafeRelease(_textFormat);
|
SafeRelease(_textFormat);
|
||||||
|
|
||||||
HRESULT hr = Renderer::getIDWriteFactory()->CreateTextFormat(
|
HRESULT hr = Renderer::getWriteFactory()->CreateTextFormat(
|
||||||
(const WCHAR *)_font.family,
|
(const WCHAR *)_font.family,
|
||||||
nullptr,
|
nullptr,
|
||||||
DWRITE_FONT_WEIGHT(_font.weight),
|
DWRITE_FONT_WEIGHT(_font.weight),
|
||||||
|
|
@ -390,7 +391,7 @@ void e2d::Text::_createLayout()
|
||||||
// 对文本自动换行情况下进行处理
|
// 对文本自动换行情况下进行处理
|
||||||
if (_style.wrapping)
|
if (_style.wrapping)
|
||||||
{
|
{
|
||||||
hr = Renderer::getIDWriteFactory()->CreateTextLayout(
|
hr = Renderer::getWriteFactory()->CreateTextLayout(
|
||||||
(const WCHAR *)_text,
|
(const WCHAR *)_text,
|
||||||
length,
|
length,
|
||||||
_textFormat,
|
_textFormat,
|
||||||
|
|
@ -409,7 +410,7 @@ void e2d::Text::_createLayout()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hr = Renderer::getIDWriteFactory()->CreateTextLayout((const WCHAR *)_text, length, _textFormat, 0, 0, &_textLayout);
|
hr = Renderer::getWriteFactory()->CreateTextLayout((const WCHAR *)_text, length, _textFormat, 0, 0, &_textLayout);
|
||||||
// 为防止文本对齐问题,根据刚才创建的 layout 宽度重新创建它
|
// 为防止文本对齐问题,根据刚才创建的 layout 宽度重新创建它
|
||||||
if (_textLayout)
|
if (_textLayout)
|
||||||
{
|
{
|
||||||
|
|
@ -420,7 +421,7 @@ void e2d::Text::_createLayout()
|
||||||
this->setSize(metrics.width, metrics.height);
|
this->setSize(metrics.width, metrics.height);
|
||||||
// 重新创建 layout
|
// 重新创建 layout
|
||||||
SafeRelease(_textLayout);
|
SafeRelease(_textLayout);
|
||||||
hr = Renderer::getIDWriteFactory()->CreateTextLayout((const WCHAR *)_text, length, _textFormat, _width, 0, &_textLayout);
|
hr = Renderer::getWriteFactory()->CreateTextLayout((const WCHAR *)_text, length, _textFormat, _width, 0, &_textLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -174,15 +174,15 @@ e2d::String e2d::Path::getSaveFilePath(const String& title, const String& defExt
|
||||||
OPENFILENAME ofn = { 0 };
|
OPENFILENAME ofn = { 0 };
|
||||||
wchar_t strFilename[MAX_PATH] = { 0 }; // 用于接收文件名
|
wchar_t strFilename[MAX_PATH] = { 0 }; // 用于接收文件名
|
||||||
ofn.lStructSize = sizeof(OPENFILENAME); // 结构体大小
|
ofn.lStructSize = sizeof(OPENFILENAME); // 结构体大小
|
||||||
ofn.hwndOwner = Window::getHWnd(); // 窗口句柄
|
ofn.hwndOwner = Window::getInstance()->getHWnd(); // 窗口句柄
|
||||||
ofn.lpstrFilter = L"所有文件\0*.*\0\0"; // 设置过滤
|
ofn.lpstrFilter = L"所有文件\0*.*\0\0"; // 设置过滤
|
||||||
ofn.nFilterIndex = 1; // 过滤器索引
|
ofn.nFilterIndex = 1; // 过滤器索引
|
||||||
ofn.lpstrFile = strFilename; // 接收返回的文件路径和文件名
|
ofn.lpstrFile = strFilename; // 接收返回的文件路径和文件名
|
||||||
ofn.nMaxFile = sizeof(strFilename); // 缓冲区长度
|
ofn.nMaxFile = sizeof(strFilename); // 缓冲区长度
|
||||||
ofn.lpstrInitialDir = nullptr; // 初始目录为默认
|
ofn.lpstrInitialDir = nullptr; // 初始目录为默认
|
||||||
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
|
ofn.Flags = OFN_PATHMUSTEXIST | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
|
||||||
ofn.lpstrTitle = (LPCWSTR)title; // 标题
|
ofn.lpstrTitle = (LPCWSTR)title; // 标题
|
||||||
ofn.lpstrDefExt = (LPCWSTR)defExt; // 默认追加的扩展名
|
ofn.lpstrDefExt = (LPCWSTR)defExt; // 默认追加的扩展名
|
||||||
|
|
||||||
if (GetSaveFileName(&ofn))
|
if (GetSaveFileName(&ofn))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -35,12 +35,13 @@ void e2d::Transition::onDestroy()
|
||||||
|
|
||||||
void e2d::Transition::_init(Scene * prev, Scene * next)
|
void e2d::Transition::_init(Scene * prev, Scene * next)
|
||||||
{
|
{
|
||||||
|
auto renderer = Renderer::getInstance();
|
||||||
// ´´½¨Í¼²ã
|
// ´´½¨Í¼²ã
|
||||||
HRESULT hr = Renderer::getRenderTarget()->CreateLayer(&_inLayer);
|
HRESULT hr = renderer->getRenderTarget()->CreateLayer(&_inLayer);
|
||||||
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
hr = Renderer::getRenderTarget()->CreateLayer(&_outLayer);
|
hr = renderer->getRenderTarget()->CreateLayer(&_outLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
|
|
@ -54,7 +55,7 @@ void e2d::Transition::_init(Scene * prev, Scene * next)
|
||||||
if (_outScene) _outScene->retain();
|
if (_outScene) _outScene->retain();
|
||||||
if (_inScene) _inScene->retain();
|
if (_inScene) _inScene->retain();
|
||||||
|
|
||||||
_windowSize = Window::getSize();
|
_windowSize = Window::getInstance()->getSize();
|
||||||
_outLayerParam = _inLayerParam = D2D1::LayerParameters();
|
_outLayerParam = _inLayerParam = D2D1::LayerParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -85,7 +86,7 @@ void e2d::Transition::_update()
|
||||||
|
|
||||||
void e2d::Transition::_render()
|
void e2d::Transition::_render()
|
||||||
{
|
{
|
||||||
auto pRT = Renderer::getRenderTarget();
|
auto pRT = Renderer::getInstance()->getRenderTarget();
|
||||||
|
|
||||||
if (_outScene)
|
if (_outScene)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
174
core/e2dbase.h
174
core/e2dbase.h
|
|
@ -14,9 +14,12 @@ namespace e2d
|
||||||
class Game
|
class Game
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// 获取游戏单例
|
// 获取游戏实例
|
||||||
static Game * getInstance();
|
static Game * getInstance();
|
||||||
|
|
||||||
|
// 销毁实例
|
||||||
|
static void destroyInstance();
|
||||||
|
|
||||||
// 初始化游戏
|
// 初始化游戏
|
||||||
bool init(
|
bool init(
|
||||||
const String& mutexName = L"" /* 进程互斥体名称 */
|
const String& mutexName = L"" /* 进程互斥体名称 */
|
||||||
|
|
@ -39,9 +42,6 @@ public:
|
||||||
// 清理资源
|
// 清理资源
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
// 销毁实例
|
|
||||||
void destroy();
|
|
||||||
|
|
||||||
// 重置游戏内部计时
|
// 重置游戏内部计时
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
|
|
@ -51,6 +51,8 @@ public:
|
||||||
private:
|
private:
|
||||||
Game();
|
Game();
|
||||||
|
|
||||||
|
~Game();
|
||||||
|
|
||||||
E2D_DISABLE_COPY(Game);
|
E2D_DISABLE_COPY(Game);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -78,82 +80,101 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// 获取窗口实例
|
||||||
|
static Window * getInstance();
|
||||||
|
|
||||||
|
// 销毁窗口实例
|
||||||
|
static void destroyInstance();
|
||||||
|
|
||||||
|
// 创建新窗口
|
||||||
|
bool create(
|
||||||
|
const String& title,
|
||||||
|
int width,
|
||||||
|
int height
|
||||||
|
);
|
||||||
|
|
||||||
// 修改窗口大小
|
// 修改窗口大小
|
||||||
static void setSize(
|
void setSize(
|
||||||
int width, /* 窗口宽度 */
|
int width, /* 窗口宽度 */
|
||||||
int height /* 窗口高度 */
|
int height /* 窗口高度 */
|
||||||
);
|
);
|
||||||
|
|
||||||
// 设置窗口标题
|
// 设置窗口标题
|
||||||
static void setTitle(
|
void setTitle(
|
||||||
const String& title /* 窗口标题 */
|
const String& title /* 窗口标题 */
|
||||||
);
|
);
|
||||||
|
|
||||||
// 设置窗口图标
|
// 设置窗口图标
|
||||||
static void setIcon(
|
void setIcon(
|
||||||
int iconID
|
int iconID
|
||||||
);
|
);
|
||||||
|
|
||||||
// 设置鼠标指针样式
|
// 设置鼠标指针样式
|
||||||
static void setCursor(
|
void setCursor(
|
||||||
Cursor cursor
|
Cursor cursor
|
||||||
);
|
);
|
||||||
|
|
||||||
// 获取窗口标题
|
// 获取窗口标题
|
||||||
static String getTitle();
|
String getTitle();
|
||||||
|
|
||||||
// 获取窗口宽度
|
// 获取窗口宽度
|
||||||
static double getWidth();
|
double getWidth();
|
||||||
|
|
||||||
// 获取窗口高度
|
// 获取窗口高度
|
||||||
static double getHeight();
|
double getHeight();
|
||||||
|
|
||||||
// 获取窗口大小
|
// 获取窗口大小
|
||||||
static Size getSize();
|
Size getSize();
|
||||||
|
|
||||||
// 获取窗口句柄
|
// 获取窗口句柄
|
||||||
static HWND getHWnd();
|
HWND getHWnd();
|
||||||
|
|
||||||
// 打开/隐藏控制台
|
// 打开/隐藏控制台
|
||||||
static void showConsole(
|
void showConsole(
|
||||||
bool show = true
|
bool show = true
|
||||||
);
|
);
|
||||||
|
|
||||||
// 是否允许响应输入法
|
// 是否允许响应输入法
|
||||||
static void setTypewritingEnable(
|
void setTypewritingEnable(
|
||||||
bool enable
|
bool enable
|
||||||
);
|
);
|
||||||
|
|
||||||
// 弹出提示窗口
|
// 弹出提示窗口
|
||||||
static void info(
|
void info(
|
||||||
const String& text, /* 内容 */
|
const String& text, /* 内容 */
|
||||||
const String& title = L"Infomation" /* 窗口标题 */
|
const String& title = L"Infomation" /* 窗口标题 */
|
||||||
);
|
);
|
||||||
|
|
||||||
// 弹出警告窗口
|
// 弹出警告窗口
|
||||||
static void warning(
|
void warning(
|
||||||
const String& text, /* 内容 */
|
const String& text, /* 内容 */
|
||||||
const String& title = L"Warning" /* 窗口标题 */
|
const String& title = L"Warning" /* 窗口标题 */
|
||||||
);
|
);
|
||||||
|
|
||||||
// 弹出错误窗口
|
// 弹出错误窗口
|
||||||
static void error(
|
void error(
|
||||||
const String& text, /* 内容 */
|
const String& text, /* 内容 */
|
||||||
const String& title = L"Error" /* 窗口标题 */
|
const String& title = L"Error" /* 窗口标题 */
|
||||||
);
|
);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// 初始化窗口
|
Window();
|
||||||
static bool __init();
|
|
||||||
|
|
||||||
// 重置窗口属性
|
~Window();
|
||||||
static void __uninit();
|
|
||||||
|
E2D_DISABLE_COPY(Window);
|
||||||
|
|
||||||
// 处理窗口消息
|
// 处理窗口消息
|
||||||
static void __poll();
|
void __poll();
|
||||||
|
|
||||||
// Win32 窗口消息回调程序
|
// Win32 窗口消息回调程序
|
||||||
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
private:
|
||||||
|
HWND _hWnd;
|
||||||
|
Size _size;
|
||||||
|
String _title;
|
||||||
|
static Window * _instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -389,67 +410,86 @@ class Renderer
|
||||||
friend class Window;
|
friend class Window;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// 获取渲染器实例
|
||||||
|
static Renderer * getInstance();
|
||||||
|
|
||||||
|
// 销毁实例
|
||||||
|
static void destroyInstance();
|
||||||
|
|
||||||
// 获取背景色
|
// 获取背景色
|
||||||
static Color getBackgroundColor();
|
Color getBackgroundColor();
|
||||||
|
|
||||||
// 修改背景色
|
// 修改背景色
|
||||||
static void setBackgroundColor(
|
void setBackgroundColor(
|
||||||
Color color
|
Color color
|
||||||
);
|
);
|
||||||
|
|
||||||
// 显示 FPS
|
// 显示 FPS
|
||||||
static void showFps(
|
void showFps(
|
||||||
bool show = true
|
bool show = true
|
||||||
);
|
);
|
||||||
|
|
||||||
// 获取系统 DPI 缩放
|
// 获取文字渲染器
|
||||||
static float getDpiScaleX();
|
TextRenderer * getTextRenderer();
|
||||||
|
|
||||||
// 获取系统 DPI 缩放
|
|
||||||
static float getDpiScaleY();
|
|
||||||
|
|
||||||
// 获取 ID2D1Factory 对象
|
|
||||||
static ID2D1Factory * getID2D1Factory();
|
|
||||||
|
|
||||||
// 获取 ID2D1HwndRenderTarget 对象
|
// 获取 ID2D1HwndRenderTarget 对象
|
||||||
static ID2D1HwndRenderTarget * getRenderTarget();
|
ID2D1HwndRenderTarget * getRenderTarget();
|
||||||
|
|
||||||
// 获取 ID2D1SolidColorBrush 对象
|
// 获取 ID2D1SolidColorBrush 对象
|
||||||
static ID2D1SolidColorBrush * getSolidColorBrush();
|
ID2D1SolidColorBrush * getSolidColorBrush();
|
||||||
|
|
||||||
|
// 获取 ID2D1Factory 对象
|
||||||
|
static ID2D1Factory * getFactory();
|
||||||
|
|
||||||
// 获取 IWICImagingFactory 对象
|
// 获取 IWICImagingFactory 对象
|
||||||
static IWICImagingFactory * getIWICImagingFactory();
|
static IWICImagingFactory * getImagingFactory();
|
||||||
|
|
||||||
// 获取 IDWriteFactory 对象
|
// 获取 IDWriteFactory 对象
|
||||||
static IDWriteFactory * getIDWriteFactory();
|
static IDWriteFactory * getWriteFactory();
|
||||||
|
|
||||||
// 获取文字渲染器
|
// 获取 FPS 文本格式化对象
|
||||||
static TextRenderer * getTextRenderer();
|
static IDWriteTextFormat * getFpsTextFormat();
|
||||||
|
|
||||||
// 获取 Miter 样式的 ID2D1StrokeStyle
|
// 获取 Miter 样式的 ID2D1StrokeStyle
|
||||||
static ID2D1StrokeStyle * getMiterID2D1StrokeStyle();
|
static ID2D1StrokeStyle * getMiterStrokeStyle();
|
||||||
|
|
||||||
// 获取 Bevel 样式的 ID2D1StrokeStyle
|
// 获取 Bevel 样式的 ID2D1StrokeStyle
|
||||||
static ID2D1StrokeStyle * getBevelID2D1StrokeStyle();
|
static ID2D1StrokeStyle * getBevelStrokeStyle();
|
||||||
|
|
||||||
// 获取 Round 样式的 ID2D1StrokeStyle
|
// 获取 Round 样式的 ID2D1StrokeStyle
|
||||||
static ID2D1StrokeStyle * getRoundID2D1StrokeStyle();
|
static ID2D1StrokeStyle * getRoundStrokeStyle();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// 渲染游戏画面
|
Renderer();
|
||||||
static void __render();
|
|
||||||
|
|
||||||
// 创建设备无关资源
|
~Renderer();
|
||||||
static bool __createDeviceIndependentResources();
|
|
||||||
|
E2D_DISABLE_COPY(Renderer);
|
||||||
|
|
||||||
|
// 渲染游戏画面
|
||||||
|
void __render();
|
||||||
|
|
||||||
// 创建设备相关资源
|
// 创建设备相关资源
|
||||||
static bool __createDeviceResources();
|
bool __createDeviceResources();
|
||||||
|
|
||||||
// 删除设备相关资源
|
// 删除设备相关资源
|
||||||
static void __discardDeviceResources();
|
void __discardDeviceResources();
|
||||||
|
|
||||||
// 删除所有渲染相关资源
|
private:
|
||||||
static void __discardResources();
|
bool _showFps;
|
||||||
|
D2D1_COLOR_F _clearColor;
|
||||||
|
ID2D1HwndRenderTarget* _renderTarget;
|
||||||
|
ID2D1SolidColorBrush* _solidBrush;
|
||||||
|
TextRenderer* _textRenderer;
|
||||||
|
|
||||||
|
static ID2D1Factory* _d2dFactory;
|
||||||
|
static IWICImagingFactory* _imagingFactory;
|
||||||
|
static IDWriteFactory* _writeFactory;
|
||||||
|
static IDWriteTextFormat* _textFormat;
|
||||||
|
static ID2D1StrokeStyle* _miterStrokeStyle;
|
||||||
|
static ID2D1StrokeStyle* _bevelStrokeStyle;
|
||||||
|
static ID2D1StrokeStyle* _roundStrokeStyle;
|
||||||
|
static Renderer * _instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -457,9 +497,11 @@ private:
|
||||||
class GC
|
class GC
|
||||||
{
|
{
|
||||||
friend class Game;
|
friend class Game;
|
||||||
friend class Object;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// 获取 GC 实例
|
||||||
|
static GC* getInstance();
|
||||||
|
|
||||||
// 保留对象
|
// 保留对象
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
static inline void retain(Type*& p)
|
static inline void retain(Type*& p)
|
||||||
|
|
@ -482,22 +524,34 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// 通知 GC 回收垃圾内存
|
// 通知 GC 回收垃圾内存
|
||||||
static void notify();
|
void notify();
|
||||||
|
|
||||||
// 手动回收垃圾内存
|
// 手动回收垃圾内存
|
||||||
static void flush();
|
void flush();
|
||||||
|
|
||||||
private:
|
|
||||||
// 将对象放入 GC
|
// 将对象放入 GC
|
||||||
static void __add(
|
void addObject(
|
||||||
Object * pObject
|
Object * pObject
|
||||||
);
|
);
|
||||||
|
|
||||||
// 更新 GC
|
|
||||||
static void __update();
|
|
||||||
|
|
||||||
// 清空所有对象
|
// 清空所有对象
|
||||||
static void __clear();
|
void clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
GC() {}
|
||||||
|
|
||||||
|
~GC();
|
||||||
|
|
||||||
|
E2D_DISABLE_COPY(GC);
|
||||||
|
|
||||||
|
// 更新 GC
|
||||||
|
void __update();
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _notifyed;
|
||||||
|
std::set<Object*> _pool;
|
||||||
|
|
||||||
|
static GC _instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -81,13 +81,17 @@
|
||||||
|
|
||||||
#if _MSC_VER >= 1800
|
#if _MSC_VER >= 1800
|
||||||
# define E2D_OP_EXPLICIT explicit
|
# define E2D_OP_EXPLICIT explicit
|
||||||
# define E2D_DELETE = delete
|
|
||||||
#else
|
#else
|
||||||
# define E2D_OP_EXPLICIT
|
# define E2D_OP_EXPLICIT
|
||||||
# define E2D_DELETE
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define E2D_DISABLE_COPY(ClassName)\
|
#if _MSC_VER >= 1800
|
||||||
ClassName(const ClassName &); \
|
# define E2D_DISABLE_COPY(Class) \
|
||||||
ClassName & operator= (const ClassName &) E2D_DELETE
|
Class(const Class &) = delete; \
|
||||||
|
Class & operator= (const Class &) = delete
|
||||||
|
#else
|
||||||
|
# define E2D_DISABLE_COPY(Class) \
|
||||||
|
Class(const Class &); \
|
||||||
|
Class & operator= (const Class &)
|
||||||
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue