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