微软文档:Geometries overview

本篇通过官方文档学习,整理出来的demo,初始样本请先创建一个普通的desktop app。

// Test_Direct2D_Brush.cpp : Defines the entry point for the application.
// #include "framework.h"
#include "Test_Direct2D_Brush.h"
#include <d2d1.h>
#include <wincodec.h> #pragma comment(lib, "D2d1.lib")
#pragma comment(lib, "Windowscodecs.lib") #define MAX_LOADSTRING 100 template <class T> void SafeRelease(T** ppT)
{
if (*ppT)
{
(*ppT)->Release();
*ppT = NULL;
}
} HWND hWnd;
ID2D1Factory* l;
ID2D1HwndRenderTarget* m_pRenderTarget;
ID2D1SolidColorBrush* m_pSceneBrush;
ID2D1GradientStopCollection* pGradientStops = NULL;
ID2D1RadialGradientBrush* m_pRadialGradientBrush;
ID2D1EllipseGeometry* m_pEllipseGeometry1, * m_pEllipseGeometry2, * m_pEllipseGeometry3, * m_pEllipseGeometry4, *m_pCircleGeometry1,*m_pCircleGeometry2;
ID2D1GeometryGroup* m_pGeoGroup_AlternateFill,*m_pGeoGroup_WindingFill;
ID2D1RectangleGeometry* m_pRectangleGeometry;
ID2D1TransformedGeometry *m_pTransformedGeometry;
ID2D1GeometrySink* pGeometrySink = NULL;
ID2D1PathGeometry* m_pPathGeometryUnion,* m_pLeftMountainGeometry,* m_pRightMountainGeometry,* m_pSunGeometry,* m_pRiverGeometry;
ID2D1Geometry* pGeometry;
ID2D1SimplifiedGeometrySink* pGeometrySink1; // Global Variables:
HINSTANCE hInst; // current instance
WCHAR szTitle[MAX_LOADSTRING]; // The title bar text
WCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name // Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
void Render();
void DiscardGraphicsResources();
void Geometry(); int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine); // TODO: Place code here. // Initialize global strings
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_TESTDIRECT2DBRUSH, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance); // Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
} HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TESTDIRECT2DBRUSH)); MSG msg; // Main message loop:
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} return (int) msg.wParam;
} //
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TESTDIRECT2DBRUSH));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_TESTDIRECT2DBRUSH);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); return RegisterClassExW(&wcex);
} //
// FUNCTION: InitInstance(HINSTANCE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // Store instance handle in our global variable
HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &l);
hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr); if (!hWnd)
{
return FALSE;
} ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd); return TRUE;
} //
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
// PAINTSTRUCT ps;
// HDC hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code that uses hdc here...
Render();
ValidateRect(hWnd, NULL);
// EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
} // Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE; case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
} void Render()
{
RECT rc;
GetClientRect(hWnd, &rc); D2D1_SIZE_U size = D2D1::SizeU(
rc.right - rc.left,
rc.bottom - rc.top
);
HRESULT hr = l->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(hWnd, size),
&m_pRenderTarget
); m_pRenderTarget->BeginDraw(); m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
/*************************************************************************************/
Geometry(); /*************************************************************************************/
hr = m_pRenderTarget->EndDraw(); if (FAILED(hr) || hr == D2DERR_RECREATE_TARGET)
{
DiscardGraphicsResources();
}
} void DiscardGraphicsResources()
{
SafeRelease(&m_pRenderTarget);
} void Geometry()
{
HRESULT hr = l->CreateEllipseGeometry(
D2D1::Ellipse(D2D1::Point2F(160.f, 120.f), 25.f, 25.f),
&m_pEllipseGeometry1);
if (SUCCEEDED(hr))
{
hr = l->CreateEllipseGeometry(
D2D1::Ellipse(D2D1::Point2F(160.f, 120.f), 50.f, 50.f),
&m_pEllipseGeometry2);
}
if (SUCCEEDED(hr))
{
hr = l->CreateEllipseGeometry(
D2D1::Ellipse(D2D1::Point2F(160.f, 120.f), 75.f, 75.f),
&m_pEllipseGeometry3);
}
if (SUCCEEDED(hr))
{
hr = l->CreateEllipseGeometry(
D2D1::Ellipse(D2D1::Point2F(160.f, 120.f), 100.f, 100.f),
&m_pEllipseGeometry4);
} ID2D1Geometry* ppGeometries[] =
{
m_pEllipseGeometry1,
m_pEllipseGeometry2,
m_pEllipseGeometry3,
m_pEllipseGeometry4
};
if (SUCCEEDED(hr))
{
hr = l->CreateGeometryGroup(
D2D1_FILL_MODE_ALTERNATE,
ppGeometries,
ARRAYSIZE(ppGeometries),
&m_pGeoGroup_AlternateFill
);
} if (SUCCEEDED(hr))
{
hr = l->CreateGeometryGroup(
D2D1_FILL_MODE_WINDING,
ppGeometries,
ARRAYSIZE(ppGeometries),
&m_pGeoGroup_WindingFill
);
}
if (SUCCEEDED(hr))
{
hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::Black, 1.0F),
&m_pBlackBrush);
}
// m_pRenderTarget->DrawGeometry(m_pGeoGroup_AlternateFill, m_pBlackBrush, 2);
// m_pRenderTarget->DrawGeometry(m_pGeoGroup_WindingFill, m_pBlackBrush, 2);
/****************************************************************************************/
//变换后的几何
hr = l->CreateRectangleGeometry(
D2D1::RectF(150.f, 150.f, 200.f, 200.f),
&m_pRectangleGeometry
);
// Draw the untransformed rectangle geometry.
// m_pRenderTarget->DrawGeometry(m_pRectangleGeometry, m_pBlackBrush, 1);
//Transform the render target, then draw the rectangle geometry again.
m_pRenderTarget->SetTransform(
D2D1::Matrix3x2F::Scale(
D2D1::SizeF(3.f, 3.f),
D2D1::Point2F(175.f, 175.f)) //上面小矩形的中心点坐标
);
// m_pRenderTarget->DrawGeometry(m_pRectangleGeometry, m_pBlackBrush, 1); hr = l->CreateTransformedGeometry(
m_pRectangleGeometry,
D2D1::Matrix3x2F::Scale(
D2D1::SizeF(3.f, 3.f),
D2D1::Point2F(175.f, 175.f)),
&m_pTransformedGeometry
);
// Replace the previous render target transform.
m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); //顾名思义,上面的m_pRenderTarget->SetTransform的设置无效了 // Draw the transformed geometry.
// m_pRenderTarget->DrawGeometry(m_pTransformedGeometry, m_pBlackBrush, 1); //另一种缩放方法,不同之处在于笔的粗细没有受影响
/*****************************************************************************************/
//组合几何
// Create the first ellipse geometry to merge.
const D2D1_ELLIPSE circle1 = D2D1::Ellipse(
D2D1::Point2F(75.0f, 75.0f),
50.0f,
50.0f
);
hr = l->CreateEllipseGeometry(
circle1,
&m_pCircleGeometry1
);
if (SUCCEEDED(hr))
{
// Create the second ellipse geometry to merge.
const D2D1_ELLIPSE circle2 = D2D1::Ellipse(
D2D1::Point2F(125.0f, 75.0f),
50.0f,
50.0f
); hr = l->CreateEllipseGeometry(circle2, &m_pCircleGeometry2);
}
if (SUCCEEDED(hr))
{
//
// Use D2D1_COMBINE_MODE_UNION to combine the geometries.
//
hr = l->CreatePathGeometry(&m_pPathGeometryUnion); if (SUCCEEDED(hr))
{
hr = m_pPathGeometryUnion->Open(&pGeometrySink); if (SUCCEEDED(hr))
{
hr = m_pCircleGeometry1->CombineWithGeometry(
m_pCircleGeometry2,
D2D1_COMBINE_MODE_UNION,
NULL,
NULL,
pGeometrySink
);
} if (SUCCEEDED(hr))
{
hr = pGeometrySink->Close();
} SafeRelease(&pGeometrySink);
}
}
// m_pRenderTarget->DrawGeometry(m_pPathGeometryUnion, m_pBlackBrush, 1); // https://docs.microsoft.com/en-us/windows/win32/direct2d/direct2d-geometries-overview#widen
// widen方法还没实现
/* hr = m_pPathGeometryUnion->Open(&pGeometrySink);
if (SUCCEEDED(hr))
{
hr = pGeometry->Widen(
2,
NULL,
NULL,
pGeometrySink1
);*/
/****************************************************************************/
//Create a Complex Drawing
//左边山
hr = l->CreatePathGeometry(&m_pLeftMountainGeometry);
ID2D1GeometrySink* pSink = NULL;
hr = m_pLeftMountainGeometry->Open(&pSink);
pSink->SetFillMode(D2D1_FILL_MODE_WINDING);
pSink->BeginFigure(
D2D1::Point2F(346, 255),
D2D1_FIGURE_BEGIN_FILLED
);
D2D1_POINT_2F points[5] = {
D2D1::Point2F(267, 177),
D2D1::Point2F(236, 192),
D2D1::Point2F(212, 160),
D2D1::Point2F(156, 255),
D2D1::Point2F(346, 255),
};
pSink->AddLines(points, ARRAYSIZE(points));
pSink->EndFigure(D2D1_FIGURE_END_CLOSED);
hr = pSink->Close();
//右边山
hr = l->CreatePathGeometry(&m_pRightMountainGeometry);
if (SUCCEEDED(hr))
{
hr = m_pRightMountainGeometry->Open(&pSink);
if (SUCCEEDED(hr))
{
pSink->SetFillMode(D2D1_FILL_MODE_WINDING); pSink->BeginFigure(
D2D1::Point2F(575, 263),
D2D1_FIGURE_BEGIN_FILLED
);
D2D1_POINT_2F points[] = {
D2D1::Point2F(481, 146),
D2D1::Point2F(449, 181),
D2D1::Point2F(433, 159),
D2D1::Point2F(401, 214),
D2D1::Point2F(381, 199),
D2D1::Point2F(323, 263),
D2D1::Point2F(575, 263)
};
pSink->AddLines(points, ARRAYSIZE(points));
pSink->EndFigure(D2D1_FIGURE_END_CLOSED);
}
hr = pSink->Close();
}
//太阳
hr = l->CreatePathGeometry(&m_pSunGeometry);
if (SUCCEEDED(hr))
{
hr = m_pSunGeometry->Open(&pSink);
if (SUCCEEDED(hr))
{
pSink->SetFillMode(D2D1_FILL_MODE_WINDING); pSink->BeginFigure(
D2D1::Point2F(270, 255),
D2D1_FIGURE_BEGIN_FILLED
);
pSink->AddArc(
D2D1::ArcSegment(
D2D1::Point2F(440, 255), // end point
D2D1::SizeF(85, 85),
0.0f, // rotation angle
D2D1_SWEEP_DIRECTION_CLOCKWISE,
D2D1_ARC_SIZE_SMALL
));
pSink->EndFigure(D2D1_FIGURE_END_CLOSED); pSink->BeginFigure(
D2D1::Point2F(299, 182),
D2D1_FIGURE_BEGIN_HOLLOW
);
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(299, 182),
D2D1::Point2F(294, 176),
D2D1::Point2F(285, 178)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(276, 179),
D2D1::Point2F(272, 173),
D2D1::Point2F(272, 173)
));
pSink->EndFigure(D2D1_FIGURE_END_OPEN); pSink->BeginFigure(
D2D1::Point2F(354, 156),
D2D1_FIGURE_BEGIN_HOLLOW
);
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(354, 156),
D2D1::Point2F(358, 149),
D2D1::Point2F(354, 142)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(349, 134),
D2D1::Point2F(354, 127),
D2D1::Point2F(354, 127)
));
pSink->EndFigure(D2D1_FIGURE_END_OPEN); pSink->BeginFigure(
D2D1::Point2F(322, 164),
D2D1_FIGURE_BEGIN_HOLLOW
);
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(322, 164),
D2D1::Point2F(322, 156),
D2D1::Point2F(314, 152)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(306, 149),
D2D1::Point2F(305, 141),
D2D1::Point2F(305, 141)
));
pSink->EndFigure(D2D1_FIGURE_END_OPEN); pSink->BeginFigure(
D2D1::Point2F(385, 164),
D2D1_FIGURE_BEGIN_HOLLOW
);
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(385, 164),
D2D1::Point2F(392, 161),
D2D1::Point2F(394, 152)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(395, 144),
D2D1::Point2F(402, 141),
D2D1::Point2F(402, 142)
));
pSink->EndFigure(D2D1_FIGURE_END_OPEN); pSink->BeginFigure(
D2D1::Point2F(408, 182),
D2D1_FIGURE_BEGIN_HOLLOW
);
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(408, 182),
D2D1::Point2F(416, 184),
D2D1::Point2F(422, 178)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(428, 171),
D2D1::Point2F(435, 173),
D2D1::Point2F(435, 173)
));
pSink->EndFigure(D2D1_FIGURE_END_OPEN);
}
hr = pSink->Close();
}
//河流
hr = l->CreatePathGeometry(&m_pRiverGeometry); if (SUCCEEDED(hr))
{
hr = m_pRiverGeometry->Open(&pSink);
if (SUCCEEDED(hr))
{
pSink->SetFillMode(D2D1_FILL_MODE_WINDING);
pSink->BeginFigure(
D2D1::Point2F(183, 392),
D2D1_FIGURE_BEGIN_FILLED
);
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(238, 284),
D2D1::Point2F(472, 345),
D2D1::Point2F(356, 303)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(237, 261),
D2D1::Point2F(333, 256),
D2D1::Point2F(333, 256)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(335, 257),
D2D1::Point2F(241, 261),
D2D1::Point2F(411, 306)
));
pSink->AddBezier(
D2D1::BezierSegment(
D2D1::Point2F(574, 350),
D2D1::Point2F(288, 324),
D2D1::Point2F(296, 392)
));
pSink->EndFigure(D2D1_FIGURE_END_OPEN);
}
hr = pSink->Close(); SafeRelease(&pSink);
}
//着色
m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity()); m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White)); //D2D1_SIZE_F rtSize = m_pRenderTarget->GetSize();
//m_pRenderTarget->FillRectangle(
// D2D1::RectF(0, 0, rtSize.width, rtSize.height),
// m_pGridPatternBitmapBrush
//); D2D1_GRADIENT_STOP gradientStops[2];
gradientStops[0].color = D2D1::ColorF(D2D1::ColorF::Yellow, 1);
gradientStops[0].position = 0.0f;
gradientStops[1].color = D2D1::ColorF(D2D1::ColorF::OrangeRed, 1);
gradientStops[1].position = 1.0f;
hr = m_pRenderTarget->CreateGradientStopCollection(
gradientStops,
2,
D2D1_GAMMA_2_2,
D2D1_EXTEND_MODE_CLAMP,
&pGradientStops
);
m_pRenderTarget->CreateRadialGradientBrush(
D2D1::RadialGradientBrushProperties(
D2D1::Point2F(355, 255),
D2D1::Point2F(0, 0),
85,
85),
pGradientStops,
&m_pRadialGradientBrush
); hr = m_pRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::Black, 1.0F),
&m_pSceneBrush);
m_pRenderTarget->FillGeometry(m_pSunGeometry, m_pRadialGradientBrush); m_pSceneBrush->SetColor(D2D1::ColorF(D2D1::ColorF::Black, 1.f));
m_pRenderTarget->DrawGeometry(m_pSunGeometry, m_pSceneBrush, 1.f); m_pSceneBrush->SetColor(D2D1::ColorF(D2D1::ColorF::OliveDrab, 1.f));
m_pRenderTarget->FillGeometry(m_pLeftMountainGeometry, m_pSceneBrush); m_pSceneBrush->SetColor(D2D1::ColorF(D2D1::ColorF::Black, 1.f));
m_pRenderTarget->DrawGeometry(m_pLeftMountainGeometry, m_pSceneBrush, 1.f); m_pSceneBrush->SetColor(D2D1::ColorF(D2D1::ColorF::LightSkyBlue, 1.f));
m_pRenderTarget->FillGeometry(m_pRiverGeometry, m_pSceneBrush); m_pSceneBrush->SetColor(D2D1::ColorF(D2D1::ColorF::Black, 1.f));
m_pRenderTarget->DrawGeometry(m_pRiverGeometry, m_pSceneBrush, 1.f); m_pSceneBrush->SetColor(D2D1::ColorF(D2D1::ColorF::YellowGreen, 1.f));
m_pRenderTarget->FillGeometry(m_pRightMountainGeometry, m_pSceneBrush); m_pSceneBrush->SetColor(D2D1::ColorF(D2D1::ColorF::Black, 1.f));
m_pRenderTarget->DrawGeometry(m_pRightMountainGeometry, m_pSceneBrush, 1.f);
}

效果图:

注意: 代码中创建的各种对象都没有释放,如在实际项目中使用该代码需要在使用完释放它们。

几何部分的内容略多,我仅对几个常用的几何形状的代码进行了整理,并且因为窗口的大小问题,一些绘制其他几何的代码被我注释了,详细可见代码。

拓展:Direct2D有专门的篇幅介绍了缩放问题,见: Scaling geometry realizations

Direct2D 几何篇的更多相关文章

  1. Direct2D 几何计算和几何变幻

    D2D不仅可以绘制,还可以对多个几何图形对象进行空间运算.这功能应该在GIS界比较吃香. 这些计算包括: 合并几何对象,可以设置求交还是求并,CombineWithGeometry 边界,加宽边界,查 ...

  2. C#LeetCode刷题-几何

    几何篇 # 题名 刷题 通过率 难度 587 安装栅栏   21.5% 困难 892 三维形体的表面积 C#LeetCode刷题之#892-三维形体的表面积(Surface Area of 3D Sh ...

  3. TGL站长关于常见问题的回复

    问题地址: http://www.thegrouplet.com/thread-112923-1-1.html 问题: 网站配有太多的模板是否影响网站加载速度 月光答复: wp不需要删除其他的模板,不 ...

  4. Direct2D教程VIII——几何(Geometry)对象的运算,本系列的终结篇

    目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...

  5. Direct2D教程VII——变换几何(TransformedGeometry)对象

    目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...

  6. Direct2D教程(外篇)环境配置

    2014年世界杯首场淘汰赛马上开始了,闲着没事,整理以前的博客草稿打发时间,意外的发现这篇文章,本来是打算加入到Direct2D那个系列的,不知道为什么把它给遗漏了.环境配置,对于熟手来说,不是什么重 ...

  7. Direct2D教程III——几何(Geometry)对象

    目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...

  8. Direct2D 第6篇 绘制多种风格的线条

    原文:Direct2D 第6篇 绘制多种风格的线条 上图是使用Direct2D绘制的线条,Direct2D在效率上比GDI/GDI+要快几倍,GDI/GDI+绘图是出了名的"慢", ...

  9. Direct2D 第5篇 绘制图像

    原文:Direct2D 第5篇 绘制图像 我加载的图像是一张透明底PNG图像,背景使用渐变的绿色画刷 #include <windows.h> #include <d2d1.h> ...

  10. Direct2D 第4篇 渐变画刷

    原文:Direct2D 第4篇 渐变画刷 #include <windows.h> #include <d2d1.h> #include <d2d1helper.h> ...

随机推荐

  1. [转帖]TIDB_HOT_REGIONS

    https://docs.pingcap.com/zh/tidb/stable/information-schema-tidb-hot-regions TIDB_HOT_REGIONS 表提供了关于当 ...

  2. [转帖]Python学习之十七_django的入门

    Python学习之十七_django的入门 前言 Python学习了一周, 慢慢总结摸索. 自己还是有多不会的地方. 感慨这些年浪费的时间. 所有的时间都是选择大于努力. 努力最多感动自己. 生活是需 ...

  3. Oracle存储过程的基本学习

    Oracle存储过程的基本学习 摘要 这个简要学习应该会分为上下两部分 第一部分是存储过程的学习. 第二部分是python的学习. 核心目标是查询Oracle数据库中的主键数据. 如果有主键upper ...

  4. [转帖]传输层安全协议真(TLS)的安全吗?

    https://zhuanlan.zhihu.com/p/305161227 随着数字通信,计算机网络,公钥密码体制等技术的迅速发展,安全网络通信已经成为了人们的日常需求.TLS 作为目前被广泛应用的 ...

  5. [转帖]浅谈Redis大Key与热Key

    https://www.cnblogs.com/jelly12345/p/16424080.html 如何定义大 Key 和 热 Key 如何定义大 Key 如何定义热 Key 大 Key 和 热 K ...

  6. 部署于K8S集群上面应用性能影响点推测

    前言 本人2017年第一次接触K8S. 中间断断续续学习K8S相关的内容. 但是最近一年,几乎没太有学习. 因为之前学习了四五年, 一直以为产品马上要用 结果一直被浇冷水. 去年开始学乖了. 不这么搞 ...

  7. Unity下调试ToLua(基于IDEA和VSCode)

    公司移动端项目是基于Unity的,底层支持由C#提供,上层Lua调用C#中注册的函数支持来做业务逻辑,框架用的是ToLua.开始做移动端有一段时间了,一直都觉得调试代码是个很蛋疼的体验:几乎都是靠肉眼 ...

  8. 隐私集合求交(PSI)协议研究综述

    摘要 隐私集合求交(PSI)是安全多方计算(MPC)中的一种密码学技术,它允许参与计算的双方,在不获取对方额外信息(除交集外的其它信息)的基础上,计算出双方数据的交集.隐私集合求交在数据共享,广告转化 ...

  9. Gorm 入门介绍与基本使用

    Gorm 入门介绍与基本使用 目录 Gorm 入门介绍与基本使用 一.ORM简介 1.1 什么是ORM 1.2 使用ORM的好处 1.2.1 避免直接操作SQL语句 1.2.2 提高代码的可维护性 1 ...

  10. 【1】Anaconda安装超简洁教程,配置环境、创建虚拟环境、添加镜像源

    相关文章: [1]Anaconda安装超简洁教程,瞬间学会! [2]Anaconda下:ipython文件的打开方式,Jupyter Notebook中运行.py文件,快速打开ipython文件的方法 ...