• Direct2D教程(五)复合图形


    概述

    Direct2D支持以下几种类型的几何图形。
    Simple Geometry(简单几何图形)

    •     矩形
    •     圆角矩形
    •     椭圆

    Path Geometry(路径图形)
    Composite Geometry(复合图形)

    •     Geometry Group(图形组)
    •     Transformed Geometry(变换的图形)

    上一篇介绍了Path geometry,这篇介绍复合图形。复合图形也可以叫做合成图形,包含两种,一种是图形组,即由多个图形组成的一组图形,另一种是经过变换的图形,D2D支持的变换有四种,平移,旋转,缩放和倾斜。

    图形组

    由于图形组是一组图形的集合,所以如果对图形组进行操作,会影响到其中每一个图形,这对批量操作图形是很方便的。图形组在D2D中用接口ID2D1GeometryGroup来表示。创建图形组使用函数ID2D1Factory::CreateGeometryGroup,它的定义如下

    virtual HRESULT CreateGeometryGroup(
        D2D1_FILL_MODE fillMode,
        [
    in] ID2D1Geometry **geometries,
        UINT geometriesCount,
        [
    out] ID2D1GeometryGroup **geometryGroup
    )
    0;

    第一个参数表示填充模式,可以是D2D1_FILL_MODE_ALTERNATE或者D2D1_FILL_MODE_WINDING,关于这两者的详细说明,后面有述。第二个参数是一个类型为ID2D1Geometry的数组,这个数组中包含了所有将被放入图形组的图形,第三个参数是数组中元素的个数,最后一个参数用来接收创建后的ID2D1GeometryGroup。 使用GeometryGroup的步骤如下。

    创建图形组中的所有图形

    这里我们创建四个同心圆,为了简化程序,只给出第一个圆的创建代码。创建其他的圆只需更改一下半径即可。

    const D2D1_ELLIPSE ellipse1 = D2D1::Ellipse(
        D2D1::Point2F(
    105.0f, 105.0f),
        25.0f,
        25.0f
    );

    hr
    = pD2DFactory->CreateEllipseGeometry(
        ellipse1,
        &pEllipseGeometry1
    );

    创建图形组

    先将所有的图形放到一个数组里面

    ID2D1Geometry *ppGeometries[] =
    {
        pEllipseGeometry1,
        pEllipseGeometry2,
        pEllipseGeometry3,
        pEllipseGeometry4
    };

    然后使用CreateGeometryGroup来创建图形组。

    hr = pD2DFactory->CreateGeometryGroup(
        D2D1_FILL_MODE_ALTERNATE,
        ppGeometries,
        ARRAYSIZE(ppGeometries),
        &pGeoGroup_AlternateFill
    );

    使用图形组进行绘制

    对图形组的绘制,就是对组中所有的图形进行绘制。

    pRenderTarget->FillGeometry(pGeoGroup_AlternateFill, pFillBrush);
    pRenderTarget
    ->DrawGeometry(pGeoGroup_AlternateFill, pStrokeBrush, 1.0f);

    D2D1_FILL_MODE_ALTERNATE和D2D1_FILL_MODE_WINDING这两个模式的区别见下图,两者线条的颜色都是一样的,只是填充色一个是交替模式,一个是统一模式。

    变换图形

    在2D中变换图形主要有两种方式,一是对图形所在的Render target进行变换,二是对图形本身进行变换。这两者是有区别的,对render target进行变换将影响到render target上所有的图形,而对图形本身进行变换则只影响图形自己,而且这种方式只改变图形的填充,而不改变其轮廓(也即line width)。这里我们主要介绍如何对图形本身进行变换。函数CreateTransformedGeometry可以创建一个变换后的图形。该函数定义如下

    virtual HRESULT CreateTransformedGeometry(
        [
    in] ID2D1Geometry *sourceGeometry,
        [
    in, optional] const D2D1_MATRIX_3X2_F *transform,
        [
    out] ID2D1TransformedGeometry **transformedGeometry
    )
    0;

    第一个参数sourceGeometry表示待变换的图形,第二个参数表示变换用的矩阵,最后一个参数用来存放变换后的结果。举个例子,下面的代码将pPathGeometry沿X轴和Y轴分别平移100个单位距离。平移后的图形保存在pTransformedGeometry中。

    hr = pD2DFactory->CreateTransformedGeometry(
        pPathGeometry,
        D2D1::Matrix3x2F::Translation(
    100, 100),
        &pTransformedGeometry
    );

    前面说了对图形本身进行变换不影响线条的宽度,而对render target进行变换则会影响,来看一下两者的区别,我们以缩放变换为例。

    变换render target

    // 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 = m_pD2DFactory->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());

    // Draw the transformed geometry.
    m_pRenderTarget->DrawGeometry(m_pTransformedGeometry, m_pBlackBrush, 1);

    效果图如下,注意,矩形的线条保持原样。

    Happy Coding!!!

    == THE END ==

    作者:zdd
    出处:http://www.cnblogs.com/graphics/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    微博深度学习平台架构和实践
    2020暑期学习
    2020春季学期个人课程总结
    人月神话阅读笔记03
    人月深化阅读笔记02
    第十六周学习总结
    人月神话阅读笔记01
    三分算法
    [SDOI2010]魔法猪学院
    【洛谷】NOIP2018原创模拟赛DAY1解题报告
  • 原文地址:https://www.cnblogs.com/graphics/p/2060095.html
Copyright © 2020-2023  润新知