CppUtils/Graphics/Graphics.cpp

869 lines
36 KiB
C++
Raw Normal View History

2025-06-05 10:06:43 +08:00
#include "Graphics.h"
#include "../Utils/Convert.h"
D2DGraphics::D2DGraphics()
{
pD2DDeviceContext = NULL;
Default_Brush = NULL;
Default_Brush_Back = NULL;
pD2DTargetBitmap = NULL;
DefaultFontObject = NULL;
}
D2DGraphics::D2DGraphics(UINT width, UINT height) {
HRESULT hr = S_OK;
hr = _D2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, &pD2DDeviceContext);
D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_GDI_COMPATIBLE, D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED));
hr = pD2DDeviceContext->CreateBitmap(D2D1::SizeU(width, height), NULL, 0, &bitmapProperties, &pD2DTargetBitmap);
if FAILED(hr)
return;
pD2DDeviceContext->SetTarget(pD2DTargetBitmap);
ConfigDefaultObjects();
}
D2DGraphics::D2DGraphics(ID2D1Bitmap1* bmp) {
HRESULT hr = S_OK;
pD2DTargetBitmap = bmp;
hr = _D2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_ENABLE_MULTITHREADED_OPTIMIZATIONS, &pD2DDeviceContext);
if FAILED(hr)
return;
pD2DDeviceContext->SetTarget(pD2DTargetBitmap);
ConfigDefaultObjects();
}
D2DGraphics::~D2DGraphics() {
delete DefaultFontObject;
pD2DDeviceContext->Release();
Default_Brush->Release();
Default_Brush_Back->Release();
if (pD2DTargetBitmap)
pD2DTargetBitmap->Release();
}
void D2DGraphics::ConfigDefaultObjects() {
this->DefaultFontObject = new Font(L"Arial", 18);
D2D1_COLOR_F color = D2D1_COLOR_F{ 0.5f,0.6f,0.7f,1.0f };
pD2DDeviceContext->CreateSolidColorBrush(color, &this->Default_Brush);
this->Default_Brush->SetColor(color);
pD2DDeviceContext->CreateSolidColorBrush(color, &this->Default_Brush_Back);
this->Default_Brush_Back->SetColor(color);
}
ID2D1SolidColorBrush* D2DGraphics::GetColorBrush(D2D1_COLOR_F newcolor) {
this->Default_Brush->SetColor(newcolor);
return this->Default_Brush;
}
ID2D1SolidColorBrush* D2DGraphics::GetColorBrush(COLORREF newcolor) {
this->Default_Brush->SetColor(D2D1_COLOR_F{ GetRValue(newcolor) / 255.0f,GetGValue(newcolor) / 255.0f,GetBValue(newcolor) / 255.0f,1.0f });
return this->Default_Brush;
}
ID2D1SolidColorBrush* D2DGraphics::GetColorBrush(int r, int g, int b) {
this->Default_Brush->SetColor(D2D1_COLOR_F{ r / 255.0f,g / 255.0f,b / 255.0f,1.0f });
return this->Default_Brush;
}
ID2D1SolidColorBrush* D2DGraphics::GetColorBrush(float r, float g, float b, float a) {
this->Default_Brush->SetColor(D2D1_COLOR_F{ r,g,b,a });
return this->Default_Brush;
}
ID2D1SolidColorBrush* D2DGraphics::GetBackColorBrush(D2D1_COLOR_F newcolor) {
this->Default_Brush_Back->SetColor(newcolor);
return this->Default_Brush_Back;
}
ID2D1SolidColorBrush* D2DGraphics::GetBackColorBrush(COLORREF newcolor) {
D2D1_COLOR_F _newcolor = { GetRValue(newcolor) / 255.0f,GetGValue(newcolor) / 255.0f,GetBValue(newcolor) / 255.0f,1.0f };
this->Default_Brush_Back->SetColor(_newcolor);
return this->Default_Brush_Back;
}
ID2D1SolidColorBrush* D2DGraphics::GetBackColorBrush(int r, int g, int b) {
D2D1_COLOR_F _newcolor = { r / 255.0f,g / 255.0f,b / 255.0f,1.0f };
this->Default_Brush_Back->SetColor(_newcolor);
return this->Default_Brush_Back;
}
ID2D1SolidColorBrush* D2DGraphics::GetBackColorBrush(float r, float g, float b, float a) {
D2D1_COLOR_F _newcolor = { r,g,b,a };
this->Default_Brush_Back->SetColor(_newcolor);
return this->Default_Brush_Back;
}
void D2DGraphics::BeginRender() {
pD2DDeviceContext->BeginDraw();
}
void D2DGraphics::EndRender() {
pD2DDeviceContext->EndDraw();
}
void D2DGraphics::ReSize(UINT width, UINT height) {}
void D2DGraphics::Clear(D2D1_COLOR_F color) {
pD2DDeviceContext->Clear(color);
}
void D2DGraphics::DrawLine(D2D1_POINT_2F p1, D2D1_POINT_2F p2, D2D1_COLOR_F color, float linewidth) {
pD2DDeviceContext->DrawLine(p1, p2, this->GetColorBrush(color), linewidth);
}
void D2DGraphics::DrawLine(float p1_x, float p1_y, float p2_x, float p2_y, D2D1_COLOR_F color, float linewidth) {
pD2DDeviceContext->DrawLine({ p1_x,p1_y }, { p2_x,p2_y }, this->GetColorBrush(color), linewidth);
}
void D2DGraphics::DrawLine(D2D1_POINT_2F p1, D2D1_POINT_2F p2, ID2D1Brush* brush, float linewidth) {
pD2DDeviceContext->DrawLine(p1, p2, brush, linewidth);
}
void D2DGraphics::DrawLine(float p1_x, float p1_y, float p2_x, float p2_y, ID2D1Brush* brush, float linewidth) {
pD2DDeviceContext->DrawLine({ p1_x,p1_y }, { p2_x,p2_y }, brush, linewidth);
}
void D2DGraphics::DrawRect(D2D1_RECT_F rect, D2D1_COLOR_F color, float linewidth) {
pD2DDeviceContext->DrawRectangle(rect, this->GetColorBrush(color), linewidth);
}
void D2DGraphics::DrawRect(float left, float top, float width, float height, D2D1_COLOR_F color, float linewidth) {
pD2DDeviceContext->DrawRectangle({ left,top,left + width,top + height }, this->GetColorBrush(color), linewidth);
}
void D2DGraphics::DrawRoundRect(D2D1_RECT_F rect, D2D1_COLOR_F color, float linewidth, float r) {
pD2DDeviceContext->DrawRoundedRectangle(D2D1::RoundedRect(rect, r, r), this->GetColorBrush(color), linewidth);
}
void D2DGraphics::DrawRoundRect(float left, float top, float width, float height, D2D1_COLOR_F color, float linewidth, float r) {
pD2DDeviceContext->DrawRoundedRectangle(D2D1::RoundedRect(D2D1::RectF(left, top, left + width, top + height), r, r), this->GetColorBrush(color), linewidth);
}
void D2DGraphics::FillRect(D2D1_RECT_F rect, D2D1_COLOR_F color) {
pD2DDeviceContext->FillRectangle(rect, this->GetColorBrush(color));
}
void D2DGraphics::FillRect(D2D1_RECT_F rect, ID2D1Brush* brush) {
pD2DDeviceContext->FillRectangle(rect, brush);
}
void D2DGraphics::FillRect(float left, float top, float width, float height, D2D1_COLOR_F color) {
pD2DDeviceContext->FillRectangle({ left,top,left + width,top + height }, this->GetColorBrush(color));
}
void D2DGraphics::FillRect(float left, float top, float width, float height, ID2D1Brush* brush) {
pD2DDeviceContext->FillRectangle({ left,top,left + width,top + height }, brush);
}
void D2DGraphics::FillRoundRect(D2D1_RECT_F rect, D2D1_COLOR_F color, float r) {
pD2DDeviceContext->FillRoundedRectangle(D2D1::RoundedRect(rect, r, r), this->GetColorBrush(color));
}
void D2DGraphics::FillRoundRect(float left, float top, float width, float height, D2D1_COLOR_F color, float r) {
pD2DDeviceContext->FillRoundedRectangle(D2D1::RoundedRect(D2D1::RectF(left, top, left + width, top + height), r, r), this->GetColorBrush(color));
}
void D2DGraphics::DrawEllipse(D2D1_POINT_2F cent, float xr, float yr, D2D1_COLOR_F color, float linewidth) {
pD2DDeviceContext->DrawEllipse({ cent ,xr,yr }, this->GetColorBrush(color), linewidth = 1.0f);
}
void D2DGraphics::DrawEllipse(float x, float y, float xr, float yr, D2D1_COLOR_F color, float linewidth) {
pD2DDeviceContext->DrawEllipse({ {x,y} ,xr,yr }, this->GetColorBrush(color), linewidth = 1.0f);
}
void D2DGraphics::FillEllipse(D2D1_POINT_2F cent, float xr, float yr, D2D1_COLOR_F color) {
pD2DDeviceContext->FillEllipse({ cent ,xr,yr }, this->GetColorBrush(color));
}
void D2DGraphics::FillEllipse(float cx, float cy, float xr, float yr, D2D1_COLOR_F color) {
pD2DDeviceContext->FillEllipse({ {cx,cy} ,xr,yr }, this->GetColorBrush(color));
}
void D2DGraphics::DrawGeometry(ID2D1Geometry* geo, D2D1_COLOR_F color, float linewidth) {
pD2DDeviceContext->DrawGeometry(geo, this->GetColorBrush(color), linewidth);
}
void D2DGraphics::FillGeometry(ID2D1Geometry* geo, D2D1_COLOR_F color) {
pD2DDeviceContext->FillGeometry(geo, this->GetColorBrush(color));
}
void D2DGraphics::DrawGeometry(ID2D1Geometry* geo, ID2D1Brush* brush, float linewidth) {
pD2DDeviceContext->DrawGeometry(geo, brush, linewidth);
}
void D2DGraphics::FillGeometry(ID2D1Geometry* geo, ID2D1Brush* brush) {
pD2DDeviceContext->FillGeometry(geo, brush);
}
void D2DGraphics::FillPie(D2D1_POINT_2F center, float width, float height, float startAngle, float sweepAngle, D2D1_COLOR_F color)
{
ID2D1PathGeometry* geo = Factory::CreateGeomtry();
if (!geo) return;
ID2D1GeometrySink* tmp = NULL;
if (SUCCEEDED(geo->Open(&tmp))) {
tmp->BeginFigure(center, D2D1_FIGURE_BEGIN_FILLED);
float startRad = startAngle * (3.14159265359f / 180.0f);
float sweepRad = sweepAngle * (3.14159265359f / 180.0f);
D2D1_POINT_2F startPoint = { center.x + (width / 2) * cosf(startRad),center.y - (height / 2) * sinf(startRad) };
tmp->AddLine(startPoint);
D2D1_SIZE_F arcSize = { width / 2, height / 2 };
D2D1_ARC_SIZE arcSizeFlag = (sweepAngle <= 180.0f) ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE;
tmp->AddArc(D2D1::ArcSegment(center,arcSize,0.0f,D2D1_SWEEP_DIRECTION_CLOCKWISE,arcSizeFlag));
tmp->EndFigure(D2D1_FIGURE_END_CLOSED);
tmp->Close();
pD2DDeviceContext->FillGeometry(geo, this->GetColorBrush(color));
tmp->Release();
}
geo->Release();
}
void D2DGraphics::FillPie(D2D1_POINT_2F center, float width, float height, float startAngle, float sweepAngle, ID2D1Brush* brush)
{
ID2D1PathGeometry* geo = Factory::CreateGeomtry();
if (!geo) return;
ID2D1GeometrySink* tmp = NULL;
if (SUCCEEDED(geo->Open(&tmp))) {
tmp->BeginFigure(center, D2D1_FIGURE_BEGIN_FILLED);
float startRad = startAngle * (3.14159265359f / 180.0f);
float sweepRad = sweepAngle * (3.14159265359f / 180.0f);
D2D1_POINT_2F startPoint = { center.x + (width / 2) * cosf(startRad),center.y - (height / 2) * sinf(startRad) };
tmp->AddLine(startPoint);
D2D1_SIZE_F arcSize = { width / 2, height / 2 };
D2D1_ARC_SIZE arcSizeFlag = (sweepAngle <= 180.0f) ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE;
tmp->AddArc(D2D1::ArcSegment(center, arcSize, 0.0f, D2D1_SWEEP_DIRECTION_CLOCKWISE, arcSizeFlag));
tmp->EndFigure(D2D1_FIGURE_END_CLOSED);
tmp->Close();
pD2DDeviceContext->FillGeometry(geo, brush);
tmp->Release();
}
geo->Release();
}
void D2DGraphics::DrawBitmap(ID2D1Bitmap* bmp, float x, float y, float opacity) {
D2D1_SIZE_F siz = bmp->GetSize();
pD2DDeviceContext->DrawBitmap(bmp, D2D1::RectF(x, y, siz.width + x, siz.height + y), opacity);
}
void D2DGraphics::DrawBitmap(ID2D1Bitmap* bmp, D2D1_RECT_F rect, float opacity) {
pD2DDeviceContext->DrawBitmap(bmp, rect, opacity);
}
void D2DGraphics::DrawBitmap(ID2D1Bitmap* bmp, D2D1_RECT_F destRect, D2D1_RECT_F srcRect, float opacity) {
pD2DDeviceContext->DrawBitmap(bmp, destRect, opacity, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, srcRect);
}
void D2DGraphics::DrawBitmap(ID2D1Bitmap* bmp, float x, float y, float w, float h, float opacity) {
D2D1_RECT_F rect = D2D1::RectF(x, y, w + x, h + y);
pD2DDeviceContext->DrawBitmap(bmp, rect, opacity);
}
void D2DGraphics::DrawBitmap(ID2D1Bitmap* bmp, float dest_x, float dest_y, float dest_w, float dest_h, float src_x, float src_y, float src_w, float src_h, float opacity) {
pD2DDeviceContext->DrawBitmap(bmp, D2D1::RectF(dest_x, dest_y, dest_w + dest_x, dest_h + dest_y), opacity, D2D1_BITMAP_INTERPOLATION_MODE_LINEAR, D2D1::RectF(src_x, src_y, src_w + src_x, src_h + src_y));
}
IDWriteTextLayout* D2DGraphics::CreateStringLayout(std::wstring str, float width, float height, Font* font) {
IDWriteTextLayout* textLayout = NULL;
IDWriteTextFormat* fnt = font ? font->FontObject : this->DefaultFontObject->FontObject;
_DWriteFactory->CreateTextLayout(str.c_str(), str.size(), fnt, width, height, &textLayout);
return textLayout;
}
void D2DGraphics::DrawStringLayout(IDWriteTextLayout* layout, float x, float y, D2D1_COLOR_F color) {
pD2DDeviceContext->DrawTextLayout(D2D1::Point2F(x, y), layout, this->GetColorBrush(color));
}
void D2DGraphics::DrawStringLayout(IDWriteTextLayout* layout, float x, float y, ID2D1Brush* brush) {
pD2DDeviceContext->DrawTextLayout(D2D1::Point2F(x, y), layout, brush);
}
void D2DGraphics::DrawStringLayoutEffect(IDWriteTextLayout* layout, float x, float y, D2D1_COLOR_F color, DWRITE_TEXT_RANGE subRange, D2D1_COLOR_F fontBack, Font* font) {
layout->SetDrawingEffect(NULL, DWRITE_TEXT_RANGE{ 0, UINT_MAX });
layout->SetDrawingEffect(this->GetBackColorBrush(fontBack), subRange);
pD2DDeviceContext->DrawTextLayout(D2D1::Point2F(x, y), layout, this->GetColorBrush(color));
}
void D2DGraphics::DrawStringLayoutEffect(IDWriteTextLayout* layout, float x, float y, ID2D1Brush* brush, DWRITE_TEXT_RANGE subRange, D2D1_COLOR_F fontBack, Font* font) {
layout->SetDrawingEffect(NULL, DWRITE_TEXT_RANGE{ 0, UINT_MAX });
layout->SetDrawingEffect(this->GetBackColorBrush(fontBack), subRange);
pD2DDeviceContext->DrawTextLayout(D2D1::Point2F(x, y), layout, brush);
}
void D2DGraphics::DrawString(std::wstring str, float x, float y, D2D1_COLOR_F color, Font* font) {
D2D1_RECT_F rect = D2D1::RectF(x, y, FLT_MAX, FLT_MAX);
pD2DDeviceContext->DrawText(str.c_str(), str.size(), (font ? font : this->DefaultFontObject)->FontObject, &rect, this->GetColorBrush(color));
}
void D2DGraphics::DrawString(std::wstring str, float x, float y, ID2D1Brush* brush, Font* font) {
D2D1_RECT_F rect = D2D1::RectF(x, y, FLT_MAX, FLT_MAX);
auto fnt = font ? font->FontObject : this->DefaultFontObject->FontObject;
pD2DDeviceContext->DrawText(str.c_str(), str.size(), fnt, &rect, brush);
}
void D2DGraphics::DrawString(std::wstring str, float x, float y, float w, float h, D2D1_COLOR_F color, Font* font) {
IDWriteTextLayout* textLayout = CreateStringLayout(str, w, h, font ? font : this->DefaultFontObject);
if (!textLayout) return;
pD2DDeviceContext->DrawTextLayout({ x,y }, textLayout, this->GetColorBrush(color));
textLayout->Release();
}
void D2DGraphics::DrawString(std::wstring str, float x, float y, float w, float h, ID2D1Brush* brush, Font* font) {
IDWriteTextLayout* textLayout = CreateStringLayout(str, w, h, font ? font : this->DefaultFontObject);
if (!textLayout) return;
pD2DDeviceContext->DrawTextLayout({ x,y }, textLayout, brush);
textLayout->Release();
}
void D2DGraphics::FillTriangle(D2D1_TRIANGLE triangle, D2D1_COLOR_F color) {
ID2D1PathGeometry* geo = Factory::CreateGeomtry();
if (!geo) return;
ID2D1GeometrySink* tmp = NULL;
if SUCCEEDED(geo->Open(&tmp)) {
tmp->BeginFigure(triangle.point1, D2D1_FIGURE_BEGIN_FILLED);
tmp->AddLine(triangle.point2);
tmp->AddLine(triangle.point3);
tmp->AddLine(triangle.point1);
tmp->EndFigure(D2D1_FIGURE_END::D2D1_FIGURE_END_CLOSED);
tmp->Close();
pD2DDeviceContext->FillGeometry(geo, this->GetColorBrush(color));
tmp->Release();
}
geo->Release();
}
void D2DGraphics::DrawTriangle(D2D1_TRIANGLE triangle, D2D1_COLOR_F color, float width) {
this->DrawLine(triangle.point1, triangle.point2, color, width);
this->DrawLine(triangle.point2, triangle.point3, color, width);
this->DrawLine(triangle.point3, triangle.point1, color, width);
}
void D2DGraphics::FillPolygon(std::vector<D2D1_POINT_2F> points, D2D1_COLOR_F color) {
if (points.size() > 2) {
ID2D1PathGeometry* geo = Factory::CreateGeomtry();
if (!geo) return;
ID2D1GeometrySink* tmp = NULL;
if SUCCEEDED(geo->Open(&tmp)) {
tmp->BeginFigure(points.begin()[0], D2D1_FIGURE_BEGIN_FILLED);
tmp->AddLines(points.data() + 1, points.size() - 1);
tmp->EndFigure(D2D1_FIGURE_END::D2D1_FIGURE_END_CLOSED);
tmp->Close();
pD2DDeviceContext->FillGeometry(geo, this->GetColorBrush(color));
tmp->Release();
}
geo->Release();
}
}
void D2DGraphics::FillPolygon(std::initializer_list<D2D1_POINT_2F> points, D2D1_COLOR_F color) {
if (points.size() > 2) {
ID2D1PathGeometry* geo = Factory::CreateGeomtry();
if (!geo) return;
ID2D1GeometrySink* tmp = NULL;
if SUCCEEDED(geo->Open(&tmp)) {
tmp->BeginFigure(points.begin()[0], D2D1_FIGURE_BEGIN_FILLED);
tmp->AddLines(points.begin() + 1, points.size() - 1);
tmp->EndFigure(D2D1_FIGURE_END::D2D1_FIGURE_END_CLOSED);
tmp->Close();
pD2DDeviceContext->FillGeometry(geo, this->GetColorBrush(color));
tmp->Release();
}
geo->Release();
}
}
void D2DGraphics::DrawPolygon(std::initializer_list<D2D1_POINT_2F> points, D2D1_COLOR_F color, float width) {
if (points.size() > 1) {
ID2D1PathGeometry* geo = Factory::CreateGeomtry();
if (!geo) return;
ID2D1GeometrySink* tmp = NULL;
if SUCCEEDED(geo->Open(&tmp)) {
tmp->BeginFigure(points.begin()[0], D2D1_FIGURE_BEGIN_HOLLOW);
tmp->AddLines(points.begin() + 1, points.size() - 1);
tmp->EndFigure(D2D1_FIGURE_END::D2D1_FIGURE_END_OPEN);
tmp->Close();
pD2DDeviceContext->DrawGeometry(geo, this->GetColorBrush(color), width);
tmp->Release();
}
this->DrawGeometry(geo, color, width);
geo->Release();
}
}
void D2DGraphics::DrawPolygon(std::vector<D2D1_POINT_2F> points, D2D1_COLOR_F color, float width) {
if (points.size() > 1) {
ID2D1PathGeometry* geo = Factory::CreateGeomtry();
if (!geo) return;
ID2D1GeometrySink* tmp = NULL;
if SUCCEEDED(geo->Open(&tmp)) {
tmp->BeginFigure(points[0], D2D1_FIGURE_BEGIN_HOLLOW);
tmp->AddLines(points.data() + 1, points.size() - 1);
tmp->EndFigure(D2D1_FIGURE_END::D2D1_FIGURE_END_OPEN);
tmp->Close();
pD2DDeviceContext->DrawGeometry(geo, this->GetColorBrush(color), width);
tmp->Release();
}
this->DrawGeometry(geo, color, width);
geo->Release();
}
}
void D2DGraphics::DrawArc(D2D1_POINT_2F center, float size, float sa, float ea, D2D1_COLOR_F color, float width) {
const auto __AngleToPoint = [](D2D1_POINT_2F Cent, float Angle, float Len) {
return Len > 0 ? D2D1::Point2F((Cent.x + (sin(Angle * (float)M_PI / 180.0f) * Len)), (Cent.y - (cos(Angle * (float)M_PI / 180.0f) * Len))) : Cent;
};
ID2D1PathGeometry* geo = Factory::CreateGeomtry();
if (!geo) return;
float ts = sa, te = ea;
if (te < ts) te += 360.0f;
D2D1_ARC_SIZE sweep = (te - ts < 180.0f) ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE;
ID2D1GeometrySink* pSink = NULL;
if SUCCEEDED(geo->Open(&pSink)) {
auto start = __AngleToPoint(center, sa, size),end = __AngleToPoint(center, ea, size);
pSink->BeginFigure(start, D2D1_FIGURE_BEGIN_FILLED);
pSink->AddArc(D2D1::ArcSegment(end, D2D1::SizeF(size, size), 0.0f, D2D1_SWEEP_DIRECTION_CLOCKWISE, sweep));
pSink->EndFigure(D2D1_FIGURE_END::D2D1_FIGURE_END_OPEN);
pSink->Close();
pD2DDeviceContext->DrawGeometry(geo, this->GetColorBrush(color), width);
pSink->Release();
}
geo->Release();
}
void D2DGraphics::DrawArcCounter(D2D1_POINT_2F center, float size, float sa, float ea, D2D1_COLOR_F color, float width) {
const auto __AngleToPoint = [](D2D1_POINT_2F Cent, float Angle, float Len) {
return Len > 0 ? D2D1::Point2F((Cent.x + (sin(Angle * (float)M_PI / 180.0f) * Len)), (Cent.y - (cos(Angle * (float)M_PI / 180.0f) * Len))) : Cent;
};
ID2D1PathGeometry* geo = Factory::CreateGeomtry();
if (!geo) return;
float ts = sa, te = ea;
if (te < ts) te += 360.0f;
D2D1_ARC_SIZE sweep = (te - ts < 180.0f) ? D2D1_ARC_SIZE_SMALL : D2D1_ARC_SIZE_LARGE;
ID2D1GeometrySink* pSink = NULL;
if SUCCEEDED(geo->Open(&pSink)) {
auto start = __AngleToPoint(center, sa, size),end = __AngleToPoint(center, ea, size);
pSink->BeginFigure(start, D2D1_FIGURE_BEGIN_FILLED);
pSink->AddArc(D2D1::ArcSegment(end, D2D1::SizeF(size, size), 0.0f, D2D1_SWEEP_DIRECTION_COUNTER_CLOCKWISE, sweep));
pSink->EndFigure(D2D1_FIGURE_END::D2D1_FIGURE_END_OPEN);
pSink->Close();
pD2DDeviceContext->DrawGeometry(geo, this->GetColorBrush(color), width);
pSink->Release();
}
geo->Release();
}
void D2DGraphics::PushDrawRect(float left, float top, float width, float height) {
this->pD2DDeviceContext->PushAxisAlignedClip(D2D1::RectF(left, top, left + width, top + height), D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
}
void D2DGraphics::PopDrawRect() {
this->pD2DDeviceContext->PopAxisAlignedClip();
}
void D2DGraphics::SetAntialiasMode(D2D1_ANTIALIAS_MODE antialiasMode) {
pD2DDeviceContext->SetAntialiasMode(antialiasMode);
}
void D2DGraphics::SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE antialiasMode) {
pD2DDeviceContext->SetTextAntialiasMode(antialiasMode);
}
ID2D1Bitmap* D2DGraphics::CreateBitmap(IWICBitmap* wb) {
ID2D1Bitmap* bmp = NULL;
HRESULT hr = pD2DDeviceContext->CreateBitmapFromWicBitmap(wb, &bmp);
return bmp;
}
ID2D1Bitmap* D2DGraphics::CreateBitmap(std::wstring path) {
ID2D1Bitmap* bmp = NULL;
IWICBitmapDecoder* bitmapdecoder = NULL;
_ImageFactory->CreateDecoderFromFilename(path.c_str(), NULL, GENERIC_READ, WICDecodeMetadataCacheOnDemand, &bitmapdecoder);
if (bitmapdecoder) {
IWICBitmapFrameDecode* pframe = NULL;
bitmapdecoder->GetFrame(0, &pframe);
IWICFormatConverter* fmtcovter = NULL;
_ImageFactory->CreateFormatConverter(&fmtcovter);
fmtcovter->Initialize(pframe, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.0f, WICBitmapPaletteTypeCustom);
pD2DDeviceContext->CreateBitmapFromWicBitmap(fmtcovter, NULL, &bmp);
pframe->Release();
fmtcovter->Release();
bitmapdecoder->Release();
}
return bmp;
}
ID2D1Bitmap* D2DGraphics::CreateBitmap(void* data, int size) {
ID2D1Bitmap* bmp = NULL;
IWICBitmapDecoder* bitmapdecoder = NULL;
IWICStream* pStream = NULL;
HRESULT hr = _ImageFactory->CreateStream(&pStream);
if FAILED(hr)
return NULL;
hr = pStream->InitializeFromMemory((WICInProcPointer)data, size);
if FAILED(hr)
return NULL;
hr = _ImageFactory->CreateDecoderFromStream(pStream, NULL, WICDecodeMetadataCacheOnDemand, &bitmapdecoder);
if FAILED(hr)
return NULL;
if (bitmapdecoder) {
IWICBitmapFrameDecode* pframe = NULL;
bitmapdecoder->GetFrame(0, &pframe);
IWICFormatConverter* fmtcovter = NULL;
_ImageFactory->CreateFormatConverter(&fmtcovter);
fmtcovter->Initialize(pframe, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.0f, WICBitmapPaletteTypeCustom);
pD2DDeviceContext->CreateBitmapFromWicBitmap(fmtcovter, NULL, &bmp);
pframe->Release();
fmtcovter->Release();
bitmapdecoder->Release();
}
return bmp;
}
ID2D1Bitmap* D2DGraphics::CreateBitmap(HBITMAP hb) {
IWICBitmap* wb = NULL;
ID2D1Bitmap* bmp = NULL;
_ImageFactory->CreateBitmapFromHBITMAP(hb, 0, WICBitmapUsePremultipliedAlpha, &wb);
HRESULT hr = pD2DDeviceContext->CreateBitmapFromWicBitmap(wb, &bmp);
wb->Release();
return bmp;
}
ID2D1Bitmap* D2DGraphics::CreateBitmap(HICON hb) {
IWICBitmap* wb = NULL;
ID2D1Bitmap* bmp = NULL;
_ImageFactory->CreateBitmapFromHICON(hb, &wb);
pD2DDeviceContext->CreateBitmapFromWicBitmap(wb, &bmp);
wb->Release();
return bmp;
}
ID2D1Bitmap* D2DGraphics::CreateBitmap(int width, int height) {
IWICBitmap* wb = NULL;
ID2D1Bitmap* bmp = NULL;
_ImageFactory->CreateBitmap(width, height, GUID_WICPixelFormat32bppPBGRA, WICBitmapCacheOnDemand, &wb);
auto hr = pD2DDeviceContext->CreateBitmapFromWicBitmap(wb, &bmp);
wb->Release();
return bmp;
}
ID2D1Bitmap1* D2DGraphics::GetBitmap() {
return pD2DTargetBitmap;
}
ID2D1Bitmap* D2DGraphics::GetSharedBitmap() {
if (!pD2DTargetBitmap)
return NULL;
ID2D1Bitmap* sharedBitmap = NULL;
HRESULT hr = pD2DDeviceContext->CreateSharedBitmap(__uuidof(ID2D1Bitmap1), static_cast<void*>(pD2DTargetBitmap), NULL, &sharedBitmap);
return sharedBitmap;
}
IWICBitmap* D2DGraphics::GetWicBitmap() {
IWICBitmap* wic = NULL;
HRESULT hr = Factory::ExtractID2D1Bitmap1ToIWICBitmap(pD2DDeviceContext, pD2DTargetBitmap, _ImageFactory, &wic);
return wic;
}
ID2D1LinearGradientBrush* D2DGraphics::CreateLinearGradientBrush(D2D1_GRADIENT_STOP* stops, unsigned int stopcount) {
ID2D1GradientStopCollection* collection = NULL;
ID2D1LinearGradientBrush* m_LinearBrush = NULL;
if SUCCEEDED(pD2DDeviceContext->CreateGradientStopCollection(stops, stopcount, &collection)) {
pD2DDeviceContext->CreateLinearGradientBrush({}, collection, &m_LinearBrush);
collection->Release();
}
return m_LinearBrush;
}
ID2D1RadialGradientBrush* D2DGraphics::CreateRadialGradientBrush(D2D1_GRADIENT_STOP* stops, unsigned int stopcount, D2D1_POINT_2F center) {
ID2D1GradientStopCollection* collection = NULL;
ID2D1RadialGradientBrush* brush = NULL;
if SUCCEEDED(pD2DDeviceContext->CreateGradientStopCollection(stops, stopcount, &collection)) {
D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES props = {};
props.center = center;
pD2DDeviceContext->CreateRadialGradientBrush(props, collection, &brush);
collection->Release();
}
return brush;
}
ID2D1BitmapBrush* D2DGraphics::CreateitmapBrush(ID2D1Bitmap* bmp)
{
ID2D1BitmapBrush* brush = NULL;
if SUCCEEDED(pD2DDeviceContext->CreateBitmapBrush(bmp, NULL, NULL, &brush))
return brush;
return NULL;
}
ID2D1SolidColorBrush* D2DGraphics::CreateSolidColorBrush(D2D1_COLOR_F color) {
ID2D1SolidColorBrush* result = NULL;
pD2DDeviceContext->CreateSolidColorBrush(color, &result);
return result;
}
D2D1_SIZE_F D2DGraphics::Size() {
return this->pD2DDeviceContext->GetSize();
}
ID2D1Bitmap* D2DGraphics::ToBitmapFromSvg(const char* data) {
int len = strlen(data) + 1;
char* svg_text = new char[len];
memcpy(svg_text, data, len);
NSVGimage* image = nsvgParse(svg_text, "px", 96.0f);
float percen = 1.0f;
if (image->width > 4096 || image->height > 4096) {
float maxv = image->width > image->height ? image->width : image->height;
percen = 4096.0f / maxv;
}
auto subg = new D2DGraphics(image->width * percen, image->height * percen);
NSVGshape* shape;
NSVGpath* path;
subg->BeginRender();
subg->Clear(D2D1::ColorF(0, 0, 0, 0));
for (shape = image->shapes; shape != NULL; shape = shape->next) {
auto geo = Factory::CreateGeomtry();
if (geo) {
ID2D1GeometrySink* skin = NULL;
geo->Open(&skin);
if (skin) {
for (path = shape->paths; path != NULL; path = path->next) {
for (int i = 0; i < path->npts - 1; i += 3) {
float* p = &path->pts[i * 2];
if (i == 0)
skin->BeginFigure({ p[0] * percen, p[1] * percen }, D2D1_FIGURE_BEGIN_FILLED);
skin->AddBezier({ {p[2] * percen, p[3] * percen},{p[4] * percen, p[5] * percen},{p[6] * percen, p[7] * percen} });
}
skin->EndFigure(path->closed ? D2D1_FIGURE_END_CLOSED : D2D1_FIGURE_END_OPEN);
}
}
skin->Close();
}
auto _get_svg_brush = [](NSVGpaint paint, float opacity, D2DGraphics* g) ->ID2D1Brush* {
const auto ic2fc = [](int colorInt, float opacity)->D2D1_COLOR_F {
return D2D1_COLOR_F{ (float)GetRValue(colorInt) / 255.0f ,(float)GetGValue(colorInt) / 255.0f ,(float)GetBValue(colorInt) / 255.0f ,opacity };
};
switch (paint.type) {
case NSVG_PAINT_NONE: {
return NULL;
}
break;
case NSVG_PAINT_COLOR: {
return g->CreateSolidColorBrush(ic2fc(paint.color, opacity));
}
break;
case NSVG_PAINT_LINEAR_GRADIENT: {
std::vector<D2D1_GRADIENT_STOP> cols;
for (int i = 0; i < paint.gradient->nstops; i++) {
auto stop = paint.gradient->stops[i];
cols.push_back({ stop.offset, ic2fc(stop.color, opacity) });
}
return g->CreateLinearGradientBrush(cols.data(), cols.size());
}
break;
case NSVG_PAINT_RADIAL_GRADIENT: {
std::vector<D2D1_GRADIENT_STOP> cols;
for (int i = 0; i < paint.gradient->nstops; i++) {
auto stop = paint.gradient->stops[i];
cols.push_back({ stop.offset, ic2fc(stop.color, opacity) });
}
return g->CreateRadialGradientBrush(cols.data(), cols.size(), { paint.gradient->fx,paint.gradient->fy });
}
break;
}
return NULL;
};
ID2D1Brush* brush = _get_svg_brush(shape->fill, shape->opacity, subg);
if (brush) {
subg->FillGeometry(geo, brush);
brush->Release();
}
brush = _get_svg_brush(shape->stroke, shape->opacity, subg);
if (brush) {
subg->DrawGeometry(geo, brush, shape->strokeWidth);
brush->Release();
}
geo->Release();
}
nsvgDelete(image);
subg->EndRender();
auto result = (ID2D1Bitmap*)subg->GetSharedBitmap();
delete subg;
return result;
}
void D2DGraphics::SetTransform(D2D1_MATRIX_3X2_F matrix)
{
pD2DDeviceContext->SetTransform(matrix);
}
void D2DGraphics::ClearTransform()
{
pD2DDeviceContext->SetTransform(D2D1::Matrix3x2F::Identity());
}
std::vector<ID2D1Bitmap*> D2DGraphics::CreateBitmapFromGif(const char* path) {
std::vector<ID2D1Bitmap*> result = std::vector<ID2D1Bitmap*>();
ID2D1Bitmap* bmp = NULL;
IWICBitmapDecoder* bitmapdecoder = NULL;
HRESULT hr = _ImageFactory->CreateDecoderFromFilename(Convert::string_to_wstring(path).c_str(), NULL, GENERIC_READ, WICDecodeMetadataCacheOnLoad, &bitmapdecoder);
if FAILED(hr)
return result;
UINT count = 0;
bitmapdecoder->GetFrameCount(&count);
for (int i = 0; i < count; i++) {
IWICBitmapFrameDecode* pframe = NULL;
bitmapdecoder->GetFrame(i, &pframe);
IWICFormatConverter* fmtcovter = NULL;
_ImageFactory->CreateFormatConverter(&fmtcovter);
fmtcovter->Initialize(pframe, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.0f, WICBitmapPaletteTypeCustom);
pD2DDeviceContext->CreateBitmapFromWicBitmap(fmtcovter, NULL, &bmp);
pframe->Release();
fmtcovter->Release();
result.push_back(bmp);
}
bitmapdecoder->Release();
return result;
}
std::vector<ID2D1Bitmap*> D2DGraphics::CreateBitmapFromGifBuffer(void* data, int size) {
std::vector<ID2D1Bitmap*> result = std::vector<ID2D1Bitmap*>();
ID2D1Bitmap* bmp = NULL;
IWICStream* pStream = NULL;
IWICBitmapDecoder* bitmapdecoder = NULL;
HRESULT hr = _ImageFactory->CreateStream(&pStream);
if FAILED(hr)
return result;
hr = pStream->InitializeFromMemory((WICInProcPointer)data, size);
if FAILED(hr)
return result;
hr = _ImageFactory->CreateDecoderFromStream(pStream, NULL, WICDecodeMetadataCacheOnDemand, &bitmapdecoder);
if FAILED(hr)
return result;
if (bitmapdecoder) {
UINT count = 0;
bitmapdecoder->GetFrameCount(&count);
for (int i = 0; i < count; i++) {
IWICBitmapFrameDecode* pframe = NULL;
if SUCCEEDED(bitmapdecoder->GetFrame(i, &pframe)) {
IWICFormatConverter* fmtcovter = NULL;
if SUCCEEDED(_ImageFactory->CreateFormatConverter(&fmtcovter)) {
if SUCCEEDED(fmtcovter->Initialize(pframe, GUID_WICPixelFormat32bppPBGRA, WICBitmapDitherTypeNone, NULL, 0.0f, WICBitmapPaletteTypeCustom)) {
if SUCCEEDED(pD2DDeviceContext->CreateBitmapFromWicBitmap(fmtcovter, NULL, &bmp))
result.push_back(bmp);
}
fmtcovter->Release();
}
pframe->Release();
}
}
bitmapdecoder->Release();
}
return result;
}
HBITMAP D2DGraphics::CopyFromScreen(int x, int y, int width, int height) {
HDC sourceDC = GetDC(NULL);
HDC momDC = CreateCompatibleDC(sourceDC);
HBITMAP memBitmap = CreateCompatibleBitmap(sourceDC, width, height);
SelectObject(momDC, memBitmap);
BitBlt(momDC, 0, 0, width, height, sourceDC, x, y, SRCCOPY);
DeleteDC(momDC);
ReleaseDC(NULL, sourceDC);
return memBitmap;
}
HBITMAP D2DGraphics::CopyFromWidnow(HWND hWnd, int x, int y, int width, int height) {
HDC sourceDC = GetDC(hWnd);
HDC momDC;
momDC = ::CreateCompatibleDC(sourceDC);
HBITMAP memBitmap;
memBitmap = ::CreateCompatibleBitmap(sourceDC, width, height);
SelectObject(momDC, memBitmap);
BitBlt(momDC, 0, 0, width, height, sourceDC, x, y, SRCCOPY);
DeleteDC(momDC);
ReleaseDC(hWnd, sourceDC);
return memBitmap;
}
SIZE D2DGraphics::GetScreenSize(int index) {
std::vector<SIZE> sizes = std::vector<SIZE>();
auto callback = [](HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
std::vector<SIZE>* tmp = (std::vector<SIZE>*)dwData;
MONITORINFOEX miex{};
miex.cbSize = sizeof(miex);
GetMonitorInfo(hMonitor, &miex);
DEVMODE dm{};
dm.dmSize = sizeof(dm);
dm.dmDriverExtra = 0;
EnumDisplaySettings(miex.szDevice, ENUM_CURRENT_SETTINGS, &dm);
tmp->push_back(SIZE{ (int)dm.dmPelsWidth,(int)dm.dmPelsHeight });
return TRUE;
};
EnumDisplayMonitors(NULL, NULL, (MONITORENUMPROC)callback, (LPARAM)&sizes);
if (sizes.size() > index) {
return sizes[index];
}
return{ GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN) };
}
D2D1_SIZE_F D2DGraphics::GetTextLayoutSize(IDWriteTextLayout* textLayout)
{
D2D1_SIZE_F minSize = { 0,0 };
DWRITE_TEXT_METRICS metrics;
HRESULT hr = textLayout->GetMetrics(&metrics);
if SUCCEEDED(hr)
{
minSize = D2D1::Size((float)ceil(metrics.widthIncludingTrailingWhitespace), (float)ceil(metrics.height));
return minSize;
}
return D2D1_SIZE_F{ 0,0 };
}
HRESULT HwndGraphics::InitDevice() {
HRESULT hr = S_OK;
RECT rc{};
GetClientRect(hwnd, &rc);
UINT width = rc.right - rc.left;
UINT height = rc.bottom - rc.top;
DXGI_SWAP_CHAIN_DESC swapChainDesc = { 0 };
swapChainDesc.BufferDesc.Width = width;
swapChainDesc.BufferDesc.Height = height;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.OutputWindow = hwnd;
swapChainDesc.Windowed = TRUE;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Flags = 0;
hr = _DxgiFactory->CreateSwapChain(_D3DDevice, &swapChainDesc, &pSwapChain);
if FAILED(hr)
return hr;
hr = _D2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &pD2DDeviceContext);
if FAILED(hr)
return hr;
ReSize(width, height);
return S_OK;
}
HwndGraphics::HwndGraphics(HWND hWnd) {
hwnd = hWnd;
InitDevice();
ConfigDefaultObjects();
}
void HwndGraphics::ReSize(UINT width, UINT height) {
HRESULT hr = S_OK;
if (pD2DDeviceContext)
pD2DDeviceContext->SetTarget(NULL);
if (pD2DTargetBitmap) {
pD2DTargetBitmap->Release();
pD2DTargetBitmap = NULL;
}
RECT rec{};
GetClientRect(hwnd, &rec);
hr = pSwapChain->ResizeBuffers(0, width, height, DXGI_FORMAT_UNKNOWN, 0);
if FAILED(hr)
return;
IDXGISurface* dxgiBackBuffer = NULL;
hr = pSwapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer));
if FAILED(hr)
return;
D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW, D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED));
hr = pD2DDeviceContext->CreateBitmapFromDxgiSurface(dxgiBackBuffer, &bitmapProperties, &pD2DTargetBitmap);
dxgiBackBuffer->Release();
if FAILED(hr)
return;
pD2DDeviceContext->SetTarget(pD2DTargetBitmap);
}
void HwndGraphics::BeginRender() {
D2DGraphics::BeginRender();
}
void HwndGraphics::EndRender() {
D2DGraphics::EndRender();
pSwapChain->Present(1, 0);
}
void IDXGISwapChainGraphics::ReSize(UINT width, UINT height) {
HRESULT hr = S_OK;
if (pD2DDeviceContext)
pD2DDeviceContext->SetTarget(NULL);
if (pD2DTargetBitmap) {
pD2DTargetBitmap->Release();
pD2DTargetBitmap = NULL;
}
hr = pSwapChain->ResizeBuffers(0,width,height,DXGI_FORMAT_UNKNOWN,0);
if FAILED(hr)
return;
IDXGISurface* dxgiBackBuffer = NULL;
hr = pSwapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer));
if FAILED(hr)
return;
D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET, D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED));
hr = pD2DDeviceContext->CreateBitmapFromDxgiSurface(dxgiBackBuffer, &bitmapProperties, &pD2DTargetBitmap);
dxgiBackBuffer->Release();
if FAILED(hr)
return;
pD2DDeviceContext->SetTarget(pD2DTargetBitmap);
}
IDXGISwapChainGraphics::IDXGISwapChainGraphics(IDXGISwapChain* swapchain) {
HRESULT hr = S_OK;
pSwapChain = swapchain;
hr = _D2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &pD2DDeviceContext);
if FAILED(hr)
return;
DXGI_SWAP_CHAIN_DESC swapChainDesc;
hr = pSwapChain->GetDesc(&swapChainDesc);
if FAILED(hr)
return;
ReSize(swapChainDesc.BufferDesc.Width, swapChainDesc.BufferDesc.Height);
ConfigDefaultObjects();
}
void IDXGISwapChainGraphics::BeginRender() {
D2DGraphics::BeginRender();
}
void IDXGISwapChainGraphics::EndRender() {
D2DGraphics::EndRender();
pSwapChain->Present(1, 0);
}
void DxgiSurfaceGraphics::ReSize(UINT width, UINT height) {
if (pD2DDeviceContext)
pD2DDeviceContext->SetTarget(NULL);
if (pD2DTargetBitmap) {
pD2DTargetBitmap->Release();
pD2DTargetBitmap = NULL;
}
D2D1_BITMAP_PROPERTIES1 bitmapProperties = D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET, D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED));
HRESULT hr = pD2DDeviceContext->CreateBitmapFromDxgiSurface(pDxgiSurface, &bitmapProperties, &pD2DTargetBitmap);
if FAILED(hr)
return;
pD2DDeviceContext->SetTarget(pD2DTargetBitmap);
}
DxgiSurfaceGraphics::DxgiSurfaceGraphics(IDXGISurface* dxgiSurface) {
HRESULT hr = S_OK;
pDxgiSurface = dxgiSurface;
pDxgiSurface->AddRef();
hr = _D2DDevice->CreateDeviceContext(D2D1_DEVICE_CONTEXT_OPTIONS_NONE, &pD2DDeviceContext);
if FAILED(hr)
return;
ReSize(0, 0);
ConfigDefaultObjects();
}
void DxgiSurfaceGraphics::BeginRender() {
D2DGraphics::BeginRender();
}
void DxgiSurfaceGraphics::EndRender() {
D2DGraphics::EndRender();
}