前段时间稍微看了点Direct3D, 觉得挺有意思的,但是想着要有3D得先从2D开始。故开始了D2D旅行。

如标题所示,CreateHwndRenderTarget 是在用来创建一个渲染到窗口的渲染目标。

创建渲染目标并且可以使用硬件加速时,可以在计算机的GPU上分配资源。通过一次创建渲染目标并保留尽可能长的时间,您可以获得性能上的好处。您的应用程序应一次创建渲染目标,并在应用程序的生命周期内或在收到D2DERR_RECREATE_TARGET错误之前将其保留。收到此错误时,您需要重新创建渲染目标(及其创建的所有资源)。

它与CreateDCRenderTarget最大的区别,也就是GDI的绘图技巧与D2D的区别了。

我的个人理解是,前者是自己在GPU上创建渲染目标,并停留一段时间用来绘制,不用我们操心上下文的环境了。 而后者的作用是

创建一个绘制目标,以绘制到Windows图形设备接口(GDI)设备上下文。

很显然它是用来充当D2D与GDI的交互的。

这篇文档是介绍这个作用的, Direct2D and GDI Interoperability Overview

在代码上使用肯定也是有区别的。

前者的使用,可以先看D2D入门的代码,下面的代码是用来将图片绘制到窗口上,

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <Windows.h>
  5. #include <d2d1.h>
  6. #include <d2d1_1.h>
  7.  
  8. #include <wincodec.h>
  9.  
  10. #pragma comment(lib, "d2d1.lib")
  11. #pragma comment(lib, "Windowscodecs.lib")
  12.  
  13. #define SAFE_RELEASE(P) if(P){P->Release() ; P = NULL ;}
  14.  
  15. extern "C" ID2D1Bitmap * mybitmapcreate(ID2D1DCRenderTarget*);
  16. float left = 5;
  17. float top = 10;
  18. float Bottom = 10;
  19. float Right = 30;
  20. ID2D1Bitmap* pBitmap = NULL;
  21. IWICImagingFactory* pIWICFactory = NULL;
  22. HWND hWnd;
  23. ID2D1HwndRenderTarget* m_pRenderTarget;
  24.  
  25. void initize();
  26. void draw();
  27. D2D1_RECT_F myrect = D2D1::RectF(left, top, Bottom, Right);
  28. ID2D1Bitmap* mybitmap;
  29. ID2D1Factory* l;
  30. REFIID x = __uuidof(ID2D1Factory);
  31.  
  32. HRESULT LoadBitmapFromFile(
  33. ID2D1RenderTarget* pRenderTarget,
  34. IWICImagingFactory* pIWICFactory,
  35. PCWSTR uri,
  36. UINT destinationWidth,
  37. UINT destinationHeight
  38. )
  39. {
  40. HRESULT hr = S_OK;
  41.  
  42. IWICBitmapDecoder* pDecoder = NULL;
  43. IWICBitmapFrameDecode* pSource = NULL;
  44. IWICStream* pStream = NULL;
  45. IWICFormatConverter* pConverter = NULL;
  46. IWICBitmapScaler* pScaler = NULL;
  47.  
  48. hr = pIWICFactory->CreateDecoderFromFilename(
  49. uri,
  50. NULL,
  51. GENERIC_READ,
  52. WICDecodeMetadataCacheOnLoad,
  53. &pDecoder
  54. );
  55. if (SUCCEEDED(hr))
  56. {
  57.  
  58. // Create the initial frame.
  59. hr = pDecoder->GetFrame(0, &pSource);
  60. }
  61. if (SUCCEEDED(hr))
  62. {
  63. hr = pIWICFactory->CreateFormatConverter(&pConverter);
  64. }
  65. // If a new width or height was specified, create an
  66. // IWICBitmapScaler and use it to resize the image.
  67. if (destinationWidth != 0 || destinationHeight != 0)
  68. {
  69. UINT originalWidth, originalHeight;
  70. hr = pSource->GetSize(&originalWidth, &originalHeight);
  71. if (SUCCEEDED(hr))
  72. {
  73. if (destinationWidth == 0)
  74. {
  75. FLOAT scalar = static_cast<FLOAT>(destinationHeight) / static_cast<FLOAT>(originalHeight);
  76. destinationWidth = static_cast<UINT>(scalar * static_cast<FLOAT>(originalWidth));
  77. }
  78. else if (destinationHeight == 0)
  79. {
  80. FLOAT scalar = static_cast<FLOAT>(destinationWidth) / static_cast<FLOAT>(originalWidth);
  81. destinationHeight = static_cast<UINT>(scalar * static_cast<FLOAT>(originalHeight));
  82. }
  83.  
  84. hr = pIWICFactory->CreateBitmapScaler(&pScaler);
  85. if (SUCCEEDED(hr))
  86. {
  87. hr = pScaler->Initialize(
  88. pSource,
  89. destinationWidth,
  90. destinationHeight,
  91. WICBitmapInterpolationModeCubic
  92. );
  93. }
  94. if (SUCCEEDED(hr))
  95. {
  96. hr = pConverter->Initialize(
  97. pScaler,
  98. GUID_WICPixelFormat32bppPBGRA,
  99. WICBitmapDitherTypeNone,
  100. NULL,
  101. 0.f,
  102. WICBitmapPaletteTypeMedianCut
  103. );
  104. }
  105. }
  106. }
  107. if (SUCCEEDED(hr))
  108. {
  109. // Create a Direct2D bitmap from the WIC bitmap.
  110. hr = pRenderTarget->CreateBitmapFromWicBitmap(
  111. pConverter,
  112. NULL,
  113. &pBitmap
  114. );
  115. }
  116.  
  117. SAFE_RELEASE(pDecoder);
  118. SAFE_RELEASE(pSource);
  119. SAFE_RELEASE(pStream);
  120. SAFE_RELEASE(pConverter);
  121. SAFE_RELEASE(pScaler);
  122.  
  123. return TRUE;
  124. }
  125.  
  126. LRESULT CALLBACK WndProcFunc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
  127. {
  128. RECT rc;
  129. switch (message)
  130. {
  131. case WM_PAINT:
  132. {
  133. draw();
  134. }
  135. break;
  136. case WM_DESTROY:
  137. PostQuitMessage(0);
  138. return 0;
  139. }
  140. return DefWindowProc(hwnd, message, wParam, lParam);
  141. }
  142. int main(int argc, char* argv[])
  143. {
  144. WNDCLASS wc{};
  145. wc.style = CS_HREDRAW | CS_VREDRAW;
  146. wc.lpfnWndProc = WndProcFunc;
  147. wc.hInstance = GetModuleHandle(NULL);
  148. wc.lpszClassName = L"Class_Name";
  149. wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
  150. RegisterClass(&wc);
  151.  
  152. hWnd = CreateWindow(L"Class_Name", L"Test", WS_OVERLAPPEDWINDOW, 100, 100, 1000, 500, NULL, NULL, GetModuleHandle(NULL), NULL);
  153. initize();
  154.  
  155. ShowWindow(hWnd, 1);
  156. UpdateWindow(hWnd);
  157.  
  158. MSG Msg;
  159. while (GetMessage(&Msg, NULL, 0, 0))
  160. {
  161. TranslateMessage(&Msg);
  162. DispatchMessage(&Msg);
  163. }
  164.  
  165. return 0;
  166. }
  167.  
  168. void initize()
  169. {
  170. CoInitializeEx(NULL, COINIT_MULTITHREADED);
  171. CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, reinterpret_cast<void**>(&pIWICFactory));
  172.  
  173. HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &l);
  174.  
  175. RECT rc;
  176. GetClientRect(hWnd, &rc);
  177.  
  178. D2D1_SIZE_U size = D2D1::SizeU(
  179. rc.right - rc.left,
  180. rc.bottom - rc.top
  181. );
  182.  
  183. // Create a Direct2D render target.
  184. hr = l->CreateHwndRenderTarget(
  185. D2D1::RenderTargetProperties(),
  186. D2D1::HwndRenderTargetProperties(hWnd, size),
  187. &m_pRenderTarget
  188. );
  189.  
  190. }
  191.  
  192. void draw()
  193. {
  194.  
  195. LoadBitmapFromFile(m_pRenderTarget, pIWICFactory, L"timg.bmp", 650, 400);
  196.  
  197. m_pRenderTarget->BeginDraw();
  198.  
  199. m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
  200.  
  201. D2D1_SIZE_F size = pBitmap->GetSize();
  202. D2D1_POINT_2F upperLeftCorner = D2D1::Point2F(0.f, 0.f);
  203.  
  204. // Draw bitmap
  205. m_pRenderTarget->DrawBitmap(
  206. pBitmap,
  207. D2D1::RectF(
  208. upperLeftCorner.x,
  209. upperLeftCorner.y,
  210. upperLeftCorner.x + size.width,
  211. upperLeftCorner.y + size.height)
  212. );
  213. m_pRenderTarget->EndDraw();
  214.  
  215. }

后者则是需要使用ID2D1DCRenderTarget::BindDC将渲染目标绑定到向其发出绘图命令的设备上下文。

需要更改的代码部分,

  1. //创建DC的渲染目标
  2. ID2D1DCRenderTarget* pow;
  3. ...
  4.  
  5. void initize()
  6. {
  7. CoInitializeEx(NULL, COINIT_MULTITHREADED);
  8. CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IWICImagingFactory, reinterpret_cast<void**>(&pIWICFactory));
  9.  
  10. HRESULT hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &l);
  11.  
  12. D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(
  13. D2D1_RENDER_TARGET_TYPE_DEFAULT,
  14. D2D1::PixelFormat(
  15. DXGI_FORMAT_B8G8R8A8_UNORM,
  16. D2D1_ALPHA_MODE_IGNORE),
  17. 0,
  18. 0,
  19. D2D1_RENDER_TARGET_USAGE_NONE,
  20. D2D1_FEATURE_LEVEL_DEFAULT
  21. );
  22. l->CreateDCRenderTarget(&props, &pow);
  23.  
  24. }
  25. void draw()
  26. {
  27.  
  28. LoadBitmapFromFile(m_pRenderTarget, pIWICFactory, L"timg.bmp", 650, 400);
  29.  
  30. pow->BeginDraw();
  31.  
  32. pow->Clear(D2D1::ColorF(D2D1::ColorF::White));
  33.  
  34. D2D1_SIZE_F size = pBitmap->GetSize();
  35. D2D1_POINT_2F upperLeftCorner = D2D1::Point2F(0.f, 0.f);
  36.  
  37. // Draw bitmap
  38. pow->DrawBitmap(
  39. pBitmap,
  40. D2D1::RectF(
  41. upperLeftCorner.x,
  42. upperLeftCorner.y,
  43. upperLeftCorner.x + size.width,
  44. upperLeftCorner.y + size.height)
  45. );
  46. pow->EndDraw();
  47.  
  48. }
  49.  
  50. case WM_PAINT:
  51. {
  52. PAINTSTRUCT ps;
  53. HDC hdc = BeginPaint(hwnd, &ps);
  54. GetClientRect(hwnd, &rc);
  55. pow->BindDC(ps.hdc, &rc);
  56. draw();
  57. EndPaint(hwnd, &ps);
  58. }
  59. break;
  60. ...

Direct2D CreateHwndRenderTarget 和 CreateDCRenderTarget的更多相关文章

  1. Direct2D 几何图形绘制基础

    之前说过,D2D主要为了绘制有三种类型的数据:几何图形,图片,文字.这几种对象也叫做资源,资源就是要D2D流水线中要被加工的对象. 几何图形包括: 简单几何图形 直线,DrawLine,由起点和终点构 ...

  2. Direct2D教程I——简介及首个例子

    在博客园里,系统的Direct2D的教程比较少,只有“万一”写了一个关于Direct2D的系列(Delphi 2009).于是,仿照其系列,写一个在VS下的Direct2D系列教程. 博客园中的高手还 ...

  3. SharpDX之Direct2D教程I——简单示例和Color(颜色)

    研究Direct2D已经有一段时间了,也写了一个系列的文章 Direct2D ,是基于Windows API Code Pack 1.1.在前文 Direct2D教程VIII——几何(Geometry ...

  4. Direct2D教程V——位图(Bitmap)和位图笔刷(BitmapBrush)

    目前博客园中成系列的Direct2D的教程有 1.万一的 Direct2D 系列,用的是Delphi 2009 2.zdd的 Direct2D 系列,用的是VS中的C++ 3.本文所在的 Direct ...

  5. Direct2D教程(二)来看D2D世界中的Hello,World

    引子 任何一门语言的第一个教程几乎都是Hello,world.我们也不例外,但是这里不是教大家打印Hello,world,而是编写一个简单的D2D绘制程序,让大家对Direct2D的程序结构及编程方法 ...

  6. Direct2D开发:Direct2D 和 GDI 互操作性概述

    本主题说明如何结合使用 Direct2D 和 GDI(可能为英文网页).有两种方法可以结合使用 Direct2D 和 GDI:您可以将 GDI 内容写入与 Direct2D GDI 兼容的呈现器目标, ...

  7. 关于 Direct2D

    http://msdn.microsoft.com/zh-cn/library/windows/desktop/dd370987(v=vs.85).aspx 本主题介绍 Direct2D,这是 Win ...

  8. UWP中的Direct2D

    介绍 DirectX一直是Windows平台中高性能图形的代名词,自Win7开始,微软又推出了Direct2D技术,包装于Direct3D,但专注于2D图形,并且准备取代GDI这样的传统2D图形技术. ...

  9. Direct2D教程(外篇)环境配置

    2014年世界杯首场淘汰赛马上开始了,闲着没事,整理以前的博客草稿打发时间,意外的发现这篇文章,本来是打算加入到Direct2D那个系列的,不知道为什么把它给遗漏了.环境配置,对于熟手来说,不是什么重 ...

  10. Direct2D开发:纹理混合

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.概述 我们都知道Direct2D可以加载并显示图片,但是不知道你有没有想过,这个2D的图形引擎可以进行纹理混合吗?如果 ...

随机推荐

  1. [转帖]使用 Dumpling 导出数据

      16 Contributors 使用数据导出工具 Dumpling,你可以把存储在 TiDB 或 MySQL 中的数据导出为 SQL 或 CSV 格式,用于逻辑全量备份.Dumpling 也支持将 ...

  2. [转帖]3.3.8. KWR运行期对比报告 KWR DIFF

    https://help.kingbase.com.cn/v8/perfor/performance-optimization/performance-optimization-6.html#sys- ...

  3. [转帖]神秘的backlog参数与TCP连接队列

    https://www.cnblogs.com/codelogs/p/16060820.html 简介# 这要从一次压测项目说起,那是我们公司的系统与另几家同行公司的系统做性能比拼,性能数据会直接影响 ...

  4. 自建邮箱服务器 EwoMail 发送邮件的办法

    总结来源: http://doc.ewomail.com/docs/ewomail/changguipeizhi 1. 首先这个机器不能安装dovecot等软件,不然安装脚本会失败. 2. 下载安装文 ...

  5. 简单监控Tomcat连接池大小的命令以及其他简单命令

    while true ; do date && echo "当前数据库连接池大小为:" $(jmap -histo `jps |grep caf |awk '{pr ...

  6. 数据结构与算法 第二章线性表(48课时课程笔记)Data Structure and Algorithms

    2.1 线性表的类型定义 一个线性表是n个数据元素的有限序列. (1)结构初始化 InitList(&L) 构造一个空的线性表L. (2)销毁结构 DestroyList(&L) (3 ...

  7. Linux策略路由详解

    概述 在Linux中,我们通常使用route命令来做路由信息的管理.但是该命令仅仅只能用于基本路由信息的管理,面对功能更加强大的基于策略的路由机制,route命令就显得捉襟见肘.在传统路由算法中,只能 ...

  8. 机器学习从入门到放弃:卷积神经网络CNN(一)

    一.前言 在上一篇中我们使用全连接网络,来构建我们的手写数字图片识别应用,取得了很好的效果.但是值得注意的是,在实验的最后,最后我们无论把 LOSS 优化到如何低,似乎都无法在测试数据集 test d ...

  9. Jupyter Notebook支持Go

    在执行下列命令之前,请确保你已经安装了Go和Jupyter. gophernotes是针对Jupyter和nteract的Go内核,它可以让你在基于浏览器的笔记本或桌面app上交互式地使用Go.下面介 ...

  10. 19.6 Boost Asio 文本压缩传输

    Base64是一种二进制到文本的编码方案,用于将二进制数据转换为ASCII字符串格式.它通过将二进制数据流转换为一系列64个字符来工作,这些字符都可以安全地传输到设计用于处理文本数据的系统中. 如下代 ...