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/archive/2011/05/31/2060095.html,如需转载请自行联系原作者

相关文章
|
2月前
|
前端开发
Bootstrap 5 网格的基本结构 创建相等宽度的列,Bootstrap 自动布局
Bootstrap 自动布局允许创建响应式等宽或不等宽的列。例如,使用 `.col` 类可创建等宽列;使用 `.col-sm-*` 类可在不同屏幕尺寸上自定义列宽,如 `.col-sm-3` 表示在小屏幕及以上设备上占 1/4 宽度。未指定宽度的列将自动均分剩余空间。
PyQt5 技术篇-QTableWidget表格组件指定行的隐藏与显示控制实例演示,设置表格指定列的列宽方法
PyQt5 技术篇-QTableWidget表格组件指定行的隐藏与显示控制实例演示,设置表格指定列的列宽方法
709 0
PyQt5 技术篇-QTableWidget表格组件指定行的隐藏与显示控制实例演示,设置表格指定列的列宽方法
|
4月前
|
存储 机器人 API
如何使用渐变块创建自定义聊天机器人
本文是一篇使用Gradio库的Blocks API创建自定义聊天机器人界面的教程,涵盖了从基础聊天机器人到支持流式响应、用户反馈(喜欢/不喜欢)以及Markdown、图像、音频和视频等多媒体内容的高级功能实现方法。
如何使用渐变块创建自定义聊天机器人
|
7月前
|
异构计算
Pyglet shaps形状控件的种类和用法(共12种)
Pyglet shaps形状控件的种类和用法(共12种)
83 1
|
缓存 索引
OpenGL学习笔记(九):索引缓冲器(EBO /IBE)的理解与使用,引入线框/填充模式
OpenGL学习笔记(九):索引缓冲器(EBO /IBE)的理解与使用,引入线框/填充模式
OpenGL学习笔记(九):索引缓冲器(EBO /IBE)的理解与使用,引入线框/填充模式
|
缓存 Swift 开发者
OpenGL ES 案例06:GLKit使用索引绘图
OpenGL ES 案例06:GLKit使用索引绘图
145 0
OpenGL ES 案例06:GLKit使用索引绘图