Magic_Game/core/Base/Renderer.cpp

385 lines
7.6 KiB
C++
Raw Normal View History

2018-04-21 21:24:46 +08:00
#include "..\e2dbase.h"
#include "..\e2dmanager.h"
#include "..\e2dnode.h"
2018-01-30 16:45:38 +08:00
static bool s_bShowFps = false;
static float s_fDpiScaleX = 0;
static float s_fDpiScaleY = 0;
static IDWriteTextFormat * s_pTextFormat = nullptr;
2018-01-30 16:45:38 +08:00
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;
2018-01-30 16:45:38 +08:00
static D2D1_COLOR_F s_nClearColor = D2D1::ColorF(D2D1::ColorF::Black);
bool e2d::Renderer::__createDeviceIndependentResources()
2018-01-30 16:45:38 +08:00
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޹<EFBFBD><DEB9><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD>ǵ<EFBFBD><C7B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ںͳ<DABA><CDB3><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ͬ
HRESULT hr = D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
2018-01-30 16:45:38 +08:00
&s_pDirect2dFactory
);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>ǰ<EFBFBD><C7B0>ϵͳ DPI<50><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵҲ<D6B5><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (SUCCEEDED(hr))
{
s_pDirect2dFactory->GetDesktopDpi(&s_fDpiScaleX, &s_fDpiScaleY);
}
2018-05-24 12:24:39 +08:00
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
);
}
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
);
}
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
2018-01-30 16:45:38 +08:00
{
// <20><><EFBFBD><EFBFBD> WIC <20><>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳһ<CDB3><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>ʽ<EFBFBD><CABD>ͼƬ
hr = CoCreateInstance(
CLSID_WICImagingFactory,
nullptr,
2018-01-30 16:45:38 +08:00
CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory,
reinterpret_cast<void**>(&s_pIWICFactory)
);
}
2018-05-24 12:24:39 +08:00
if (FAILED(hr))
{
throw SystemException(L"Create IWICImagingFactory failed");
}
else
2018-01-30 16:45:38 +08:00
{
// <20><><EFBFBD><EFBFBD> DirectWrite <20><><EFBFBD><EFBFBD>
hr = DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&s_pDWriteFactory)
);
}
2018-05-24 12:24:39 +08:00
if (FAILED(hr))
{
throw SystemException(L"Create IDWriteFactory failed");
}
else
{
2018-04-17 11:41:33 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><C4B1><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
hr = s_pDWriteFactory->CreateTextFormat(
L"",
nullptr,
DWRITE_FONT_WEIGHT_NORMAL,
2018-04-17 11:41:33 +08:00
DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
20,
2018-04-17 11:41:33 +08:00
L"",
&s_pTextFormat
);
if (SUCCEEDED(hr))
{
s_pTextFormat->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
}
2018-04-17 11:41:33 +08:00
}
2018-01-30 16:45:38 +08:00
return SUCCEEDED(hr);
}
bool e2d::Renderer::__createDeviceResources()
2018-01-30 16:45:38 +08:00
{
HRESULT hr = S_OK;
2018-01-30 16:45:38 +08:00
if (!s_pRenderTarget)
{
HWND hWnd = Window::getHWnd();
2018-01-30 16:45:38 +08:00
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD>Щ<EFBFBD><D0A9>ԴӦ<D4B4><D3A6> Direct3D <20><EFBFBD><E8B1B8>ʧʱ<CAA7>ؽ<EFBFBD><D8BD><EFBFBD>
// <20><><EFBFBD>統 isVisiable <20><><EFBFBD>޸ģ<DEB8><C4A3>ȵ<EFBFBD>
RECT rc;
GetClientRect(hWnd, &rc);
D2D1_SIZE_U size = D2D1::SizeU(
rc.right - rc.left,
rc.bottom - rc.top
);
// <20><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> Direct2D <20><>ȾĿ<C8BE><C4BF>
hr = s_pDirect2dFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(
hWnd,
size),
&s_pRenderTarget
);
2018-05-24 12:24:39 +08:00
if (FAILED(hr))
{
throw SystemException(L"Create ID2D1HwndRenderTarget failed");
}
else
2018-02-01 09:38:25 +08:00
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˢ
hr = s_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::White),
&s_pSolidBrush
);
}
2018-05-24 12:24:39 +08:00
if (FAILED(hr))
{
throw SystemException(L"Create ID2D1SolidColorBrush failed");
}
else
{
// <20><><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ⱦ<EFBFBD><C8BE>
s_pTextRenderer = TextRenderer::Create(
s_pDirect2dFactory,
s_pRenderTarget,
s_pSolidBrush
);
}
2018-01-30 16:45:38 +08:00
}
2018-01-30 16:45:38 +08:00
return SUCCEEDED(hr);
}
void e2d::Renderer::__discardDeviceResources()
2018-01-30 16:45:38 +08:00
{
2018-05-22 12:24:43 +08:00
SafeRelease(s_pRenderTarget);
SafeRelease(s_pSolidBrush);
SafeRelease(s_pTextRenderer);
SafeRelease(s_pMiterStrokeStyle);
SafeRelease(s_pBevelStrokeStyle);
SafeRelease(s_pRoundStrokeStyle);
2018-01-30 16:45:38 +08:00
}
void e2d::Renderer::__discardResources()
2018-01-30 16:45:38 +08:00
{
2018-05-22 12:24:43 +08:00
SafeRelease(s_pTextFormat);
SafeRelease(s_pDirect2dFactory);
SafeRelease(s_pRenderTarget);
SafeRelease(s_pSolidBrush);
SafeRelease(s_pTextRenderer);
SafeRelease(s_pMiterStrokeStyle);
SafeRelease(s_pBevelStrokeStyle);
SafeRelease(s_pRoundStrokeStyle);
2018-05-22 12:24:43 +08:00
SafeRelease(s_pIWICFactory);
SafeRelease(s_pDWriteFactory);
2018-01-30 16:45:38 +08:00
}
void e2d::Renderer::__render()
2018-01-30 16:45:38 +08:00
{
HRESULT hr = S_OK;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
Renderer::__createDeviceResources();
2018-01-30 16:45:38 +08:00
// <20><>ʼ<EFBFBD><CABC>Ⱦ
s_pRenderTarget->BeginDraw();
// ʹ<>ñ<EFBFBD><C3B1><EFBFBD>ɫ<EFBFBD><C9AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ
s_pRenderTarget->Clear(s_nClearColor);
// <20><>Ⱦ<EFBFBD><C8BE><EFBFBD><EFBFBD>
SceneManager::__render();
2018-01-30 16:45:38 +08:00
2018-04-17 11:41:33 +08:00
// <20><>Ⱦ FPS
2018-05-24 12:24:39 +08:00
if (s_bShowFps && s_pTextFormat)
2018-04-17 11:41:33 +08:00
{
static int s_nRenderTimes = 0;
static double s_fLastRenderTime = 0;
static String s_sFpsText;
2018-05-14 22:51:40 +08:00
++s_nRenderTimes;
2018-04-17 11:41:33 +08:00
double fDelay = Time::getTotalTime() - s_fLastRenderTime;
if (fDelay >= 0.3)
{
s_sFpsText = String::format(L"FPS: %.1lf", (1 / fDelay) * s_nRenderTimes);
s_fLastRenderTime = Time::getTotalTime();
s_nRenderTimes = 0;
}
IDWriteTextLayout * pTextLayout = nullptr;
hr = s_pDWriteFactory->CreateTextLayout(
(const WCHAR *)s_sFpsText,
(UINT32)s_sFpsText.getLength(),
s_pTextFormat,
0,
0,
&pTextLayout
);
if (SUCCEEDED(hr))
{
s_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
s_pSolidBrush->SetOpacity(1.0f);
s_pTextRenderer->SetTextStyle(
D2D1::ColorF(D2D1::ColorF::White),
TRUE,
2018-04-22 16:14:04 +08:00
D2D1::ColorF(D2D1::ColorF::Black, 0.4f),
1.5f,
2018-04-23 17:59:46 +08:00
D2D1_LINE_JOIN_ROUND
);
pTextLayout->Draw(nullptr, s_pTextRenderer, 10, 0);
2018-05-22 12:24:43 +08:00
SafeRelease(pTextLayout);
}
2018-04-17 11:41:33 +08:00
}
2018-01-30 16:45:38 +08:00
// <20><>ֹ<EFBFBD><D6B9>Ⱦ
hr = s_pRenderTarget->EndDraw();
if (hr == D2DERR_RECREATE_TARGET)
{
// <20><><EFBFBD><EFBFBD> Direct3D <20><EFBFBD><E8B1B8>ִ<EFBFBD>й<EFBFBD><D0B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>ε<EFBFBD><CEB5><EFBFBD>ʱ<EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD>Դ
hr = S_OK;
Renderer::__discardDeviceResources();
2018-01-30 16:45:38 +08:00
}
if (FAILED(hr))
{
2018-05-24 12:24:39 +08:00
throw SystemException(L"Device loss recovery failed");
2018-01-30 16:45:38 +08:00
}
}
e2d::Color e2d::Renderer::getBackgroundColor()
2018-01-30 16:45:38 +08:00
{
return Color(s_nClearColor.r, s_nClearColor.g, s_nClearColor.b, s_nClearColor.a);
}
void e2d::Renderer::setBackgroundColor(Color color)
{
s_nClearColor = color.toD2DColorF();
2018-01-30 16:45:38 +08:00
}
2018-04-17 11:41:33 +08:00
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()
2018-01-30 16:45:38 +08:00
{
return s_pDirect2dFactory;
}
ID2D1HwndRenderTarget * e2d::Renderer::getRenderTarget()
2018-01-30 16:45:38 +08:00
{
return s_pRenderTarget;
}
ID2D1SolidColorBrush * e2d::Renderer::getSolidColorBrush()
2018-01-30 16:45:38 +08:00
{
return s_pSolidBrush;
}
IWICImagingFactory * e2d::Renderer::getIWICImagingFactory()
2018-01-30 16:45:38 +08:00
{
return s_pIWICFactory;
}
IDWriteFactory * e2d::Renderer::getIDWriteFactory()
2018-01-30 16:45:38 +08:00
{
return s_pDWriteFactory;
}
e2d::TextRenderer * e2d::Renderer::getTextRenderer()
{
return s_pTextRenderer;
}
ID2D1StrokeStyle * e2d::Renderer::getMiterID2D1StrokeStyle()
{
return s_pMiterStrokeStyle;
}
ID2D1StrokeStyle * e2d::Renderer::getBevelID2D1StrokeStyle()
{
return s_pBevelStrokeStyle;
}
ID2D1StrokeStyle * e2d::Renderer::getRoundID2D1StrokeStyle()
{
return s_pRoundStrokeStyle;
}