在进行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. [转帖]shell 使用sed或awk将文本中的上下两行合并为一行

    例如要装下面文本上下两行合并为一行 文件test内容: # cat test a1 ce ef 12 45 57 efef 5656 gfg 455 上下两行合并为一行: # sed -n '{N;s ...

  2. [转帖]Java连接 MySQL详细教程,分享复习经验和后台开发面经

    (由于安装了汉化包,英文版的用户可以对应图标来操作) 选中菜单栏文件,之后选择项目结构 选择Libraries 点击+ ![在这里插入图片描述](https://img-blog.csdnimg.cn ...

  3. 提高Unity编译dll的速度

    前言 我们有一个Unity纯C#开发的mmo项目(使用ILRuntime热更,开发阶段跑纯C#),在开发到后期之后,每次修改C#代码编译时间在25秒左右,这部分的等待时间是很长的, 我在想有没有办法可 ...

  4. 从零开始配置 vim(7)——自动命令

    这篇我们来谈论vim一个相当重要的东西--自动命令. 从编程的角度来看,自动命令有点类似于事件响应,或者回调函数之类.当外部发生某些事件的时候,自动执行事先定义好的一组命令. 定义一个自动命令的格式如 ...

  5. 7.2 Windows驱动开发:内核注册并监控对象回调

    在笔者上一篇文章<内核枚举进程与线程ObCall回调>简单介绍了如何枚举系统中已经存在的进程与线程回调,本章LyShark将通过对象回调实现对进程线程的句柄监控,在内核中提供了ObRegi ...

  6. Flask 框架:运用WTForms实现用户注册

    WTForms 是用于web开发的灵活的表单验证和呈现库,它可以与您选择的任何web框架和模板引擎一起工作,并支持数据验证.CSRF保护.国际化等,运用WTForms框架并配合Flask可实现一个带有 ...

  7. json扩展之自定义序列化方式

    简介:由于json.dumps() 只能序列化Python基本数据类型,如果我们想要在数据中掺杂时间对象,或者自定义类的对象则会造成序列化数据的失败,因此json.dumps() 提供了一个属性 cl ...

  8. C/C++可变参数模版和函数指针的结合

    目录 1.说明 2.模板类传入固定参数的C函数指针 3.模板类传入固定参数的C++函数指针 3.1.用函数对象替代函数指针存储 4.模板类传入不定参数的C函数指针 5.模板类传入不定参数的C++成员函 ...

  9. 使用window.print进行前端打印,批量打印,设置分页,ie、火狐下设置页眉页脚

    window.print() print() 方法用于打印当前窗口的内容.谷歌调用 print() 方法会产生一个打印预览弹框,让用户可以设置打印请求. 但谷歌貌似不能自定义设置页眉页脚的文字:ie和 ...

  10. Delphi库单元结构

    单元(unit)是组成Pascal 程序的单独的源代码模块,单元由函数和过程组成,这些函数和过程能被主程序调用. 一个标准的单元文件格式如下: unit Unit1: //单元头 interface ...