Direct2D渲染图形

创建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,先介绍到这了,如有错误的地方,欢迎指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值