在进行D2D学习的时候,发现了这样一篇文档,

Direct2D Quickstart for Windows 8

只有这么一小段介绍,

Direct2D is a native-code, immediate-mode API for creating 2D graphics. This topic illustrates how to use Direct2D to draw to a Windows::UI::Core::CoreWindow.

与先前使用CreateHwndRenderTarget直接创建渲染目标的方法不同,它使用的D3D中的交换链技术,也就是先创建Device,再从Device中创建context,有了context后,再在context中创建渲染对象,并将后缓存区绑定到渲染对象上。最终调用context来绘制图形。并使用交换链的技术present来显示图像。

目前不知道这个与之前d2d的绘图方法的主要区别,我猜测是性能方面可能是交换链技术更高,毕竟涉及到D3D。

以下的创建的详细步骤,

步骤1:包括Direct2D标头

除了应用程序所需的头之外,还包括d2d1.h和d2d1_1.h头。

步骤2:创建一个ID2D1Factory1

任何Direct2D示例所做的第一件事就是创建一个ID2D1Factory1

DX::ThrowIfFailed(
D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
__uuidof(ID2D1Factory1),
&options,
&m_d2dFactory
)
);

所述ID2D1Factory1接口是使用的Direct2D的起点; 使用ID2D1Factory1创建Direct2D资源。

创建工厂时,可以指定它是多线程还是单线程。(有关多线程工厂的更多信息,请参见ID2D1Factory参考页上的说明。)本示例创建一个单线程工厂。

通常,您的应用程序应创建一次工厂,并在应用程序的生命周期内保留它。

步骤3:创建一个ID2D1Device和一个ID2D1DeviceContext

创建工厂后,使用它创建Direct2D设备,然后使用该设备创建Direct2D设备上下文。为了创建这些Direct2D对象,您必须具有Direct3D 11设备DXGI设备DXGI交换链。有关创建必要先决条件的信息,请参见设备和设备上下文

   // Obtain the underlying DXGI device of the Direct3D11.1 device.
DX::ThrowIfFailed(
m_d3dDevice.As(&dxgiDevice)
); // Obtain the Direct2D device for 2-D rendering.
DX::ThrowIfFailed(
m_d2dFactory->CreateDevice(dxgiDevice.Get(), &m_d2dDevice)
); // And get its corresponding device context object.
DX::ThrowIfFailed(
m_d2dDevice->CreateDeviceContext(
D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
&m_d2dContext
)
);

设备上下文是可以执行绘图操作并创建与设备相关的绘图资源(如画笔)的设备。您还可以使用设备上下文将ID2D1Bitmap链接到DXGI曲面以用作渲染目标。设备上下文可以呈现给不同类型的目标。

此处的代码声明了位图的属性,该位图链接到渲染到CoreWindow的DXGI交换链。该ID2D1DeviceContext :: CreateBitmapFromDxgiSurface方法从表面DXGI得到了Direct2D的表面。这使得渲染到目标ID2D1Bitmap的所有内容都渲染到交换链的表面。

有了Direct2D曲面后,请使用ID2D1DeviceContext :: SetTarget方法将其设置为活动渲染目标。

   // Now we set up the Direct2D render target bitmap linked to the swapchain.
// Whenever we render to this bitmap, it will be directly rendered to the
// swapchain associated with the window.
D2D1_BITMAP_PROPERTIES1 bitmapProperties =
BitmapProperties1(
D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
m_dpi,
m_dpi
); // Direct2D needs the dxgi version of the backbuffer surface pointer.
ComPtr<IDXGISurface> dxgiBackBuffer;
DX::ThrowIfFailed(
m_swapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer))
); // Get a D2D surface from the DXGI back buffer to use as the D2D render target.
DX::ThrowIfFailed(
m_d2dContext->CreateBitmapFromDxgiSurface(
dxgiBackBuffer.Get(),
&bitmapProperties,
&m_d2dTargetBitmap
)
); // So now we can set the Direct2D render target.
m_d2dContext->SetTarget(m_d2dTargetBitmap.Get());

第4步:创建画笔

就像工厂一样,设备上下文可以创建图形资源。在此示例中,设备上下文创建画笔。

ComPtr<ID2D1SolidColorBrush> pBlackBrush;
DX::ThrowIfFailed(
m_d2dContext->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::Black),
&pBlackBrush
)
);

画笔是绘制区域的对象,例如形状的笔触或几何图形的填充。在此示例中,笔刷用预定义的纯色黑色绘制区域。

Direct2D还提供其他类型的笔刷:用于绘制线性和径向渐变的渐变笔刷,用于使用位图和图案进行绘制的位图画笔,以及从Windows 8开始使用的用于绘制渲染图像的图像笔刷

一些绘图API提供了用于绘制轮廓的笔和用于填充形状的画笔。Direct2D有所不同:它不提供笔对象,但使用笔刷绘制轮廓和填充形状。绘制轮廓时,请使用ID2D1StrokeStyle接口,或者在Windows 8中从ID2D1StrokeStyle1接口开始,使用画笔来控制路径描边操作。

画笔只能与创建画笔的渲染目标以及同一资源域中的其他渲染目标一起使用。通常,您应该只创建一次画笔,并在创建它们的渲染目标的整个生命周期内保留它们。ID2D1SolidColorBrush是唯一的异常;由于创建起来相对便宜,因此每次绘制框架时都可以创建一个ID2D1SolidColorBrush,而不会明显降低性能。您也可以使用一个ID2D1SolidColorBrush,并且每次使用时只需更改其颜色或不透明度。

步骤5:绘制矩形

接下来,使用设备上下文绘制矩形

m_d2dContext->BeginDraw();

m_d2dContext->DrawRectangle(
D2D1::RectF(
rc.left + 100.0f,
rc.top + 100.0f,
rc.right - 100.0f,
rc.bottom - 100.0f),
pBlackBrush); DX::ThrowIfFailed(
m_d2dContext->EndDraw()
); DX::ThrowIfFailed(
m_swapChain->Present1(1, 0, &parameters);
);

DrawRectangle的方法有两个参数:要绘制的矩形,并使用画笔绘制矩形的轮廓。(可选)您还可以指定笔划宽度,虚线图案,线连接和端盖选项。

您必须在发出任何绘图命令之前调用BeginDraw方法,并且在完成发出绘图命令之后必须调用EndDraw方法。该EndDraw方法返回HRESULT指示绘图命令是否成功。如果失败,则ThrowIfFailed帮助器函数将引发异常。

所述IDXGISwapChain ::Present方法是交换缓冲面与上屏幕表面,以显示结果。

Direct2D 另一种与D3D创建类似的方法的更多相关文章

  1. GoF的23种设计模式之创建型模式的特点和分类

    创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是“将对象的创建与使用分离”.这样可以降低系统的耦合度,使用者不需要关注对象的创建细节,对象的创建由相关的工厂来完成.就像我们去商场购买商品时, ...

  2. C#两种创建快捷方式的方法

    C#两种创建快捷方式的方法http://www.cnblogs.com/linmilove/archive/2009/06/10/1500989.html

  3. 【Java 线程的深入研究1】Java 提供了三种创建线程的方法

    Java 提供了三种创建线程的方法: 通过实现 Runnable 接口: 通过继承 Thread 类本身: 通过 Callable 和 Future 创建线程. 1.通过实现 Runnable 接口来 ...

  4. Linux下几种另类创建文件之方法

    以前我们用编辑器例如vi来新建文件,下面介绍几种另类生成文件的方法,多用在备份和测试上. 创建文件的方法: 1.echo 命令    #echo "set bell"  >& ...

  5. Expression Blend 的点滴(4)--创建类似iPhone屏幕锁控件(下)

    原文:Expression Blend 的点滴(4)--创建类似iPhone屏幕锁控件(下) 接着上篇... 接下去,将一步步演示如果创建当点击checkBox后,其中的按钮由左边滑动到右边,表示处于 ...

  6. Expression Blend 的点滴(4)--创建类似iPhone屏幕锁控件(上)

    原文:Expression Blend 的点滴(4)--创建类似iPhone屏幕锁控件(上) 本篇文章,最终效果图:  当然,不只是一个UI而已,如果只是一张图片,那专业的设计师能做出更出色的效果.在 ...

  7. Java四种读取和创建XML文档的例子教程

    四种方法解析XML文档:Dom.SAX.JDOM.dom4j          1.了解XML XML,即可扩展标记语言(Extensible Markup Language),标准通用标记语言的子集 ...

  8. Spring 中如何自动创建代理(spring中的三种自动代理创建器)

    Spring 提供了自动代理机制,可以让容器自动生成代理,从而把开发人员从繁琐的配置中解脱出来 . 具体是使用 BeanPostProcessor 来实现这项功能. 这三种自动代理创建器 为:Bean ...

  9. 创建用户的方法 3种mysql创建方法

    mysql创建用户的方法分成三种:INSERT USER表的方法.CREATE USER的方法.GRANT的方法.   一.账号名称的构成方式   账号的组成方式:用户名+主机(所以可以出现重复的用户 ...

  10. 创建多线程程序的第一种方式_创建Thread类的子类

    创建多线程程序的第一种方式:创建Thread类的子类java.lang.Thread类:是描述线程的类,我们想要实现多线程程序,就必须继承Thread类 实现步骤: 1.创建一个Thread类的子类 ...

随机推荐

  1. [转帖]《Linux性能优化实战》笔记(六)—— Linux 软中断与对应故障分析方法

    中断是系统用来响应硬件设备请求的一种机制,它会打断进程的正常调度和执行,然后调用内核中的中断处理程序来响应设备的请求. 一. 为什么要有中断 举个生活中的例子,让你感受一下中断的魅力.比如说你订了一份 ...

  2. [转帖]kafka_export 部署实战

    https://zhuanlan.zhihu.com/p/57704357 Kafka Exporter 监控 Kafka 实时数据 需要安装的组件 Prometheus:时序数据库,按时间保存监控历 ...

  3. [转帖]总结:Springboot监控Actuator相关

    一.介绍 由于项目中使用的仍然是比较老旧的1.5.6版本,所以本文是基于此版本进行描述. 二.Actuator使用 ActuatorActuator是Spring Boot提供的对应用系统的监控和管理 ...

  4. [转帖]2022年 SRE、DevOps技能图谱

    https://zhuanlan.zhihu.com/p/568752990 在过去一段时间,我面试过一些 DevOps 相关从业者,并且曾经收到过一些知乎小伙伴的提问,针对于 DevOps 以及相关 ...

  5. MYSQL使用mydumper备份恢复操作简介

    MYSQL使用mydumper备份恢复操作简介 1. 环境准备 第一步是进行下载安装包的操作. 在github以及官网上面有相关的安装介质. 官网为: http://www.mydumper.org/ ...

  6. 初识C语言:掌握未来的编程利器

    ​ 欢迎大家来到贝蒂大讲堂 ​ 养成好习惯,先赞后看哦~ ​ 所属专栏:C语言学习 ​ 贝蒂的主页:Betty's blog 1. C语言是什么 在我们生活中,我们和父母.朋友.老师交流时候使用的就是 ...

  7. vue3父组件方法之间方法的互相调用

    场景描述 在项目开发中.我们可能会使用父组件调用子组件中的方法 也有可能子组件中调用父组件中的方法 下面我们来看一看组件之间方法的调用 父组件页面 <template> <div&g ...

  8. TienChin 渠道管理-配置字典常量

    在字典管理当中添加渠道状态 channel_status:渠道状态 分别为: 正常,键值为1,回显样式为 success 禁用,键值为0,回显样式为 info !> 有个注意点:Vue3 当中 ...

  9. 常见的for循环优化方式

    ?> 前言 经常使用一些循环,进行耗时计算的操作,特别是 for 循环,它是一种重复计算的操作,如果处理不好,耗时就比较大,如果处理书写得当,将大大提高效率,下面总结几条 for 循环的常见优化 ...

  10. BigDecimal详解和精度问题

    JavaGuide :「Java学习+面试指南」一份涵盖大部分 Java 程序员所需要掌握的核心知识. BigDecimal 是大厂 Java 面试常问的一个知识点. <阿里巴巴 Java 开发 ...