创建D2D资源:
BOOL CreateD2DResource()
{
if (!mRenderTarget)
{
HRESULT hr;
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, &mD2D1Factory);
if (FAILED(hr))
{
return FALSE;
}
// Obtain the size of the drawing area
RECT rc;
GetClientRect(mHWnd, &rc);
//mDisplayScreen.GetClientRect(&rc);
// Create a Direct2D render target
D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat(
DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_PREMULTIPLIED
);
D2D1_RENDER_TARGET_PROPERTIES property = D2D1::RenderTargetProperties();
property.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
property.pixelFormat = pixelFormat;
//相当于设备上下文
hr = mD2D1Factory->CreateHwndRenderTarget(
property,
D2D1::HwndRenderTargetProperties(
mHWnd,
D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top)
),
&mRenderTarget
);
if (FAILED(hr))
{
return FALSE;
}
// Create a brush
hr = mRenderTarget->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::Red),
&mSolidBrush
);
if (FAILED(hr))
{
return FALSE;
}
}
return TRUE;
}
锁定和解锁设备上下文,每次渲染都要执行。
void BeginDraw()
{
ASSERT(mRenderTarget);
mRenderTarget->BeginDraw();
}
void EndDraw()
{
ASSERT(mRenderTarget);
mRenderTarget->EndDraw();
}
根据字体名称和字体高度创建字体格式:
IDWriteTextFormat* CreateTextFormat(const WCHAR* fontName, float fontHeight)
{
HRESULT hr;
IDWriteTextFormat* textFormat;
IDWriteFactory* pDWriteFactory = NULL;
// Create DirectWrite Factory
hr = DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&pDWriteFactory)
);
if (FAILED(hr))
{
return NULL;
}
hr = pDWriteFactory->CreateTextFormat(
fontName,
NULL,
DWRITE_FONT_WEIGHT_REGULAR,
DWRITE_FONT_STYLE_NORMAL,
DWRITE_FONT_STRETCH_NORMAL,
fontHeight,
L"en-us",
&textFormat
);
SAFE_RELEASE(pDWriteFactory);
if (!SUCCEEDED(hr))
{
return NULL;
}
return textFormat;
}
渲染D2D位图:
输入一个d2d位图对象和需要目标区域
void RenderBitmap(ID2D1Bitmap* bitmap, D2D1_RECT_F dstRect)
{
if (!bitmap)
{
return;
}
mRenderTarget->DrawBitmap(
bitmap,dstRect);
}
渲染一条直线:
渲染直线时需要先创建一个画刷,设置画刷的颜色、粗细、透明度
void RenderLine(D2D1_POINT_2F start, D2D1_POINT_2F end, D2D1_COLOR_F color, FLOAT strokeWidth)
{
ID2D1SolidColorBrush* colorBrush;
//创建一个实的画刷,要绘制虚线,可以创建虚线画刷
HRESULT hr = mRenderTarget->CreateSolidColorBrush(color, &colorBrush);
if (FAILED(hr))
return;
colorBrush->SetOpacity(0.5f);//设置为半透明
mRenderTarget->DrawLine(start, end, colorBrush, strokeWidth);
SAFE_RELEASE(colorBrush);
}
渲染矩形框:
// 跟渲染直线类似,矩形无填充
void RenderRect(D2D1_RECT_F rect, D2D1_COLOR_F color, FLOAT strokeWidth)
{
ID2D1SolidColorBrush* colorBrush;
HRESULT hr = mRenderTarget->CreateSolidColorBrush(color, &colorBrush);
if (FAILED(hr))
return;
mRenderTarget->DrawRectangle(rect, colorBrush, strokeWidth);
SAFE_RELEASE(colorBrush);
}
渲染一个圆角矩形:
//输入颜色和圆角的曲率半径、矩形框的粗细
void RenderRoundedRect(D2D1_RECT_F rect, D2D1_COLOR_F color, float radius, FLOAT strokeWidth)
{
ID2D1SolidColorBrush* colorBrush;
HRESULT hr = mRenderTarget->CreateSolidColorBrush(color, &colorBrush);
if (FAILED(hr))
return;
//设置圆角曲率半径
D2D1_ROUNDED_RECT roundedRect;
roundedRect.rect = rect;
roundedRect.radiusX = radius;
roundedRect.radiusY = radius;
mRenderTarget->DrawRoundedRectangle(roundedRect, colorBrush, strokeWidth);
SAFE_RELEASE(colorBrush);
}
填充一个普通矩形区域:
void FillRect(D2D1_RECT_F rect, D2D1_COLOR_F color, float opacity)
{
ID2D1SolidColorBrush* colorBrush;
HRESULT hr = mRenderTarget->CreateSolidColorBrush(color, &colorBrush);
if (FAILED(hr))
return;
colorBrush->SetOpacity(opacity);
mRenderTarget->FillRectangle(rect, colorBrush);
SAFE_RELEASE(colorBrush);
}
渲染一个填充的圆角矩形:
void FillRoundedRect(D2D1_RECT_F rect, D2D1_COLOR_F color, float radius, float opacity)
{
ID2D1SolidColorBrush* colorBrush;
HRESULT hr = mRenderTarget->CreateSolidColorBrush(color, &colorBrush);
if (FAILED(hr))
return;
colorBrush->SetOpacity(opacity);
D2D1_ROUNDED_RECT roundedRect;
roundedRect.rect = rect;
roundedRect.radiusX = radius;
roundedRect.radiusY = radius;
mRenderTarget->FillRoundedRectangle(roundedRect, colorBrush);
SAFE_RELEASE(colorBrush);
}
绘制文本:
//设置绘制区域, 文本内容,字体颜色、格式。IDWriteTextFormat中包含段落对齐方式,DWRITE_TEXT_ALIGNMENT_LEADING左对齐,DWRITE_TEXT_ALIGNMENT_TRAILING右对齐,还有居中对齐DWRITE_PARAGRAPH_ALIGNMENT_CENTER
void RenderText(D2D1_RECT_F rect, const WCHAR* text, D2D1_COLOR_F color, IDWriteTextFormat* textFormat)
{
ID2D1SolidColorBrush* colorBrush;
int len = wcslen(text);
HRESULT hr = mRenderTarget->CreateSolidColorBrush(color, &colorBrush);
if (FAILED(hr))
return;
mRenderTarget->DrawText(text, len, textFormat, rect, colorBrush);
SAFE_RELEASE(colorBrush);
}
渲染一个圆:
设置圆心和半径
void RenderCircle(D2D1_POINT_2F center, FLOAT radius, D2D1_COLOR_F color)
{
ID2D1SolidColorBrush* colorBrush;
HRESULT hr = mRenderTarget->CreateSolidColorBrush(color, &colorBrush);
if (FAILED(hr))
return;
D2D1_ELLIPSE circle;
circle.radiusX = radius;
circle.radiusY = radius;
circle.point = center;
colorBrush->SetColor(color);
colorBrush->SetOpacity(1.0f);
mRenderTarget->DrawEllipse(circle, colorBrush);
SAFE_RELEASE(colorBrush);
}
渲染一个梯变的圆:
//设置圆心、半径,起始颜色和终止颜色
void RenderGradientCircle(D2D1_POINT_2F center, FLOAT radius, D2D1_COLOR_F start, D2D1_COLOR_F end)
{
HRESULT hr;
ID2D1RadialGradientBrush* colorBrush;
D2D1_ELLIPSE circle;
circle.radiusX = circle.radiusY = radius;
circle.point = center;
//创建一个梯变收集,设置起始点颜色和终止点颜色,可以设置多个
ID2D1GradientStopCollection* gradientStopCollection;
// Create Gradient Stops
D2D1_GRADIENT_STOP gradient_stops[3];
gradient_stops[0].color = end;
gradient_stops[0].position = 0.0f;
gradient_stops[1].color = start;
gradient_stops[1].position = 1.0f;
// Create Interface
hr = mRenderTarget->CreateGradientStopCollection(gradient_stops, 3, &gradientStopCollection);
if (FAILED(hr))
{
return;
}
//创建一个圆形梯变的画刷
hr = mRenderTarget->CreateRadialGradientBrush(D2D1::RadialGradientBrushProperties(center, D2D1::Point2F(), radius, radius), gradientStopCollection, &colorBrush);
if (FAILED(hr))
return;
mRenderTarget->FillEllipse(circle, colorBrush);
SAFE_RELEASE(colorBrush);
SAFE_RELEASE(gradientStopCollection);
}
绘制圆弧:
绘制一个圆弧麻烦些,首先需要创建一个圆弧的几何图形,然后再绘制这个几何图形。
//创建一个几何图形,开的
ID2D1PathGeometry* CreatePathGeometryOpen(D2D1_POINT_2F start, D2D1_POINT_2F end, float radius, D2D1_SWEEP_DIRECTION direct, D2D1_ARC_SIZE size)
{
HRESULT hr;
ID2D1PathGeometry* arcGeometry = NULL;
if (!mD2D1Factory)
{
return NULL;
}
hr = mD2D1Factory->CreatePathGeometry(&arcGeometry);
if (SUCCEEDED(hr))
{
ID2D1GeometrySink *pSink = NULL;
hr = arcGeometry->Open(&pSink);
if (SUCCEEDED(hr))
{
pSink->SetFillMode(D2D1_FILL_MODE_WINDING);
pSink->BeginFigure(
start, // Start point of the top half circle
D2D1_FIGURE_BEGIN_FILLED
);
// Add the top half circle
//方向为顺时针或者逆时针,size为D2D1_ARC_SIZE_LARGE或者D2D1_ARC_SIZE_SMALL大圆方向还是小圆,注意不要搞混了
pSink->AddArc(
D2D1::ArcSegment(
end, // end point of the top half circle, also the start point of the bottom half circle
D2D1::SizeF(radius, radius), // radius
0.0f, // rotation angle
direct,
size
));
pSink->EndFigure(D2D1_FIGURE_END_OPEN);
}
hr = pSink->Close();
SAFE_RELEASE(pSink);
}
return arcGeometry;
}
//设置颜色和图形的粗细,渲染几何图形
void RenderGeometry(ID2D1PathGeometry* geometry, D2D1_COLOR_F color, float stroke)
{
ID2D1SolidColorBrush* solidBrush = NULL;
HRESULT hr;
ASSERT(mRenderTarget);
hr = mRenderTarget->CreateSolidColorBrush(color, &solidBrush);
if (SUCCEEDED(hr))
{
mRenderTarget->DrawGeometry(geometry, solidBrush, stroke);
}
SAFE_RELEASE(solidBrush);
}
OK,先介绍到这了,如有错误的地方,欢迎指正。