在进行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——Shell脚本参数传递的2种方法

    https://www.cnblogs.com/caoweixiong/p/12334418.html 前言 平时会遇到很多脚本都有参数选项,类似: ./test.sh -f config.conf ...

  2. [转帖]Perf IPC以及CPU性能

    https://plantegg.github.io/2021/05/16/Perf%20IPC%E4%BB%A5%E5%8F%8ACPU%E5%88%A9%E7%94%A8%E7%8E%87/ Pe ...

  3. 一个PCI-E的硬盘参数

    看了下 HDD 随机 IOPS 在 100-200 之间 (读写) SATA的 SSD 随机IOPS 在 读 100k 写 20k 左右U.2的SSD 的随机IOPS 在 读 500k 写 50k 左 ...

  4. Linux应用程序下网络栈参数的简单整理

    somaxconn 该参数应该是决定一个服务能够同时处理多少个网络请求的核心参数. 一个程序能够支持多少个访问参数,是有两部分来决定, 第一部分是somaxconn ,第二部分是应用服务器启动时传递过 ...

  5. clickhouse 优化实践,万级别QPS数据毫秒写入和亿级别数据秒级返回 | 京东云技术团队

    1.背景 魔笛活动平台目前在采集每个活动的用户行为数据并进行查询,解决线上问题定位慢,响应不及时的问题,提升客诉的解决效率.目前每天采集的数据量5000万+,一个月的数据总量15亿+,总数据量40亿+ ...

  6. React数据通信父传子和子传父的使用

    组件中的props 在react中,props的特点是: 1.可以给组件传递任意类型的数据 2.props是只读的对象,只能够读取属性的值,无法修改对象 如过我们强行修改数据,会报错,告诉我们该属性是 ...

  7. vue数据更新后在视图上不响应

    一.vue如何追踪变化 当你把一个普通的JS对象传给vue实例的data选项时, vue将遍历此对象的所有属性, 并使用 Object.defineProperty 把这些属性全部转为 getter/ ...

  8. ABP-VNext 用户权限管理系统实战----问题与解决方案

    1.swagger请求总是报:400 Bad Request,但是postman请求是没有问题 查看日志报表: 解决方案: 在 ConfigureServices 中增加如下的内容 Configure ...

  9. ABP系列文章收藏

    1.ASP.NET样板开发框架ABP系列之ABP入门教程详解: https://www.php.cn/csharp-article-380181.html 2.官网中文翻译:  https://www ...

  10. TienChin 渠道管理-表创建

    在若依当中,有个槽点,就是数据库当中的删除标识状态一般 0 是 false,1 是 true,在若依当中反而 0 是 true,1 是 false. 渠道表设计,我这里就直接贴成品的创建表 SQL: ...