转载请注明出处:http://www.cnblogs.com/Ray1024

一、引言

最近在使用Direct2D进行绘制工作中,需要实现使用Direct2D绘制网格的功能。在网上查了很多资料,终于实现了,把方法贴到这里供大家参考。

二、绘制网格

2.1 API接口

首先介绍一下绘制网格中使用到的重要接口ID2D1BitmapRenderTarget,它继承自ID2D1RenderTarget,会写入到中间纹理。对于创建与 ID2D1BitmapBrush 结合使用的图案,或缓存要反复使用的绘制数据,这十分有用。它仅仅比基类多了一个函数GetBitmap,此函数可以将内部的绘制数据输出到位图ID2D1Bitmap中,如下:

  1. 语法: virtual HRESULT GetBitmap([out] ID2D1Bitmap **bitmap) = 0;
  2. 功能: 检索此呈现器目标的位图。返回的位图可用于绘制操作。
  3. 参数: bitmap 此方法返回时,包含指向此呈现器目标的位图的指针地址。此位图可用于绘制操作。
  4. 返回值:HRESULT 如果该方法成功,则返回 S_OK 否则,将返回错误代码。HRESULT.

创建ID2D1BitmapRenderTarget对象的函数为ID2D1RenderTarget::CreateCompatibleRenderTarget,这个函数有6个重载,我们只介绍其中一个,有兴趣的朋友可以查看msdn文档,介绍如下:

  1. 语法:HRESULT CreateCompatibleRenderTarget(D2D1_SIZE_F desiredSize,[out] ID2D1BitmapRenderTarget **bitmapRenderTarget);
  2. 功能:创建新位图呈现器目标,以供在中间屏幕外绘制期间使用。新位图呈现器目标与当前呈现器目标兼容,并且与当前呈现器目标有相同的像素格式。
  3. 参数:
  4. desiredSize 以与设备无关的像素表示的新呈现器目标的所需大小。
  5. bitmapRenderTarget 此方法返回时将包含一个指针的地址,该指针指向一个新位图呈器现目标。此参数以未初始化的状态传递。
  6. 返回值:HRESULT 如果该方法成功,则返回 S_OK 否则,将返回错误代码。HRESULT.

我们还要用到位图画刷ID2D1BitmapBrush,这个接口不用特殊介绍,我们介绍一下创建画刷时需要的一个结构体,这个结构体用来描述 ID2D1BitmapBrush 的扩展模式和内插模式:

  1. struct D2D1_BITMAP_BRUSH_PROPERTIES {
  2. D2D1_EXTEND_MODE extendModeX; //一个值,用来描述画笔对超过其位图范围的区域进行水平平铺的方式。
  3. D2D1_EXTEND_MODE extendModeY; //一个值,用来描述画笔对超过其位图范围的区域进行垂直平铺的方式。
  4. D2D1_BITMAP_INTERPOLATION_MODE interpolationMode; //一个值,用来指定对位图进行缩放或旋转时使用的内插方式。
  5. };

这个结构体前两个成员的类型都是枚举类型D2D1_EXTEND_MODE,它指定画笔如何在其常规内容区域之外的区域进行绘制。如下:

  1. typedef enum {
  2. D2D1_EXTEND_MODE_CLAMP = 0,//在常规内容区域以外的所有区域重复画笔内容边上的像素。
  3. D2D1_EXTEND_MODE_WRAP = 1,//重复画笔的内容。
  4. D2D1_EXTEND_MODE_MIRROR = 2 //与 D2D1_EXTEND_MODE_WRAP 相同,但画笔的内容将翻转显示。(画笔的常规内容在绘制时不会进行转换。)
  5. } D2D1_EXTEND_MODE;

还有一个枚举类型D2D1_BITMAP_INTERPOLATION_MODE,用来指定缩放或旋转图像时所使用的算法。如下:

  1. typedef enum {
  2. D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR = 0,//使用离当前呈现像素最近的位图像素的精确颜色。
  3. D2D1_BITMAP_INTERPOLATION_MODE_LINEAR = 1 //从离当前呈现像素最近的四个位图像素来内插颜色。
  4. } D2D1_BITMAP_INTERPOLATION_MODE;

要拉伸图像,原始图像中的每个像素都必须映射到较大的图像中的一组像素。要压缩图像,原始图像中的一组像素必须映射到较小的图像中的单个像素。我们这里用不到这些,就不过多介绍了。

到这里我们所需要的API接口就介绍完了。

2.2 思路介绍

介绍完需要的API接口之后,我们来看一下实现网格绘制的思路:

  a.创建一个网格粒度大小的ID2D1BitmapRenderTarget;

  b.在ID2D1BitmapRenderTarget上绘制两条直线,分别在ID2D1BitmapRenderTarget的左边和上边;

  c.从ID2D1BitmapRenderTarget创建位图;

  d.指定画刷的的属性,让它对超过位图画刷范围外的区域进行重复绘制。

也就是说在一个位图画刷上保存一个网格,并指定画刷绘制的时候对范围外的区域进行重复绘制,如下图所示:

2.3 代码实现

这是绘制网格的代码部分:

  1. // 网格粒度
  2. float meshLength = 20.f;
  3.  
  4. // 创建bitmapRT
  5. if (SUCCEEDED(hr))
  6. {
  7. hr = m_pRT->CreateCompatibleRenderTarget(
  8. D2D1::SizeF(meshLength,meshLength),
  9. &m_pBitmapRT);
  10. }
  11.  
  12. // 创建bitmapBrush
  13. if (SUCCEEDED(hr))
  14. {
  15. m_pBitmapRT->BeginDraw();
  16. m_pBitmapRT->DrawLine(D2D1::Point2F(0,0),D2D1::Point2F(meshLength,0),m_pBrush);
  17. m_pBitmapRT->DrawLine(D2D1::Point2F(0,0),D2D1::Point2F(0,meshLength),m_pBrush);
  18. m_pBitmapRT->EndDraw();
  19.  
  20. m_pBitmapRT->GetBitmap(&m_pBitmap);
  21.  
  22. D2D1_BITMAP_BRUSH_PROPERTIES bbp;
  23. bbp.extendModeX = D2D1_EXTEND_MODE_WRAP;
  24. bbp.extendModeY = D2D1_EXTEND_MODE_WRAP;
  25. bbp.interpolationMode = D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
  26. m_pRT->CreateBitmapBrush(m_pBitmap, bbp, &m_pBitmapBrush);
  27. }

上面的代码中先创建了bitmapRT,然后在bitmapRT上绘制一个网格的两个边,再从bitmapRT上获取位图,根据位图创建位图画刷。

下面是绘制部分的代码:

  1. RECT clientRect;
  2. GetClientRect(m_hwnd, &clientRect);
  3. D2D1_RECT_F rc = D2D1::RectF(clientRect.left,clientRect.top,clientRect.right,clientRect.bottom);
  4.  
  5. // 开始绘制
  6. m_pRT->BeginDraw();
  7.  
  8. m_pRT->SetTransform(D2D1::Matrix3x2F::Identity());
  9. m_pRT->Clear(D2D1::ColorF(D2D1::ColorF::Black));
  10.  
  11. // 绘制
  12. m_pRT->FillRectangle(
  13. rc,
  14. m_pBitmapBrush);
  15.  
  16. // 结束绘制
  17. hr = m_pRT->EndDraw();

绘制的演示效果如下图:

在这里完整代码代码就不贴出了,有兴趣的朋友可以点击此处下载Demo源码,Demo源码是Direct2DTests目录下的D2DMesh文件。

三、结语

这样我们就成功地利用Direct2D绘制出了网格,希望可以帮到大家。

[Direct2D开发] 绘制网格的更多相关文章

  1. Direct2D开发:绘制网格

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.引言 最近在使用Direct2D进行绘制工作中,需要实现使用Direct2D绘制网格的功能.在网上查了很多资料,终于实 ...

  2. untiy绘制网格mesh

    关于绘制网格, 雨松前辈 已经解释的非常的到位,这里我只是搬运工,实在是感觉自己去描述的话不会有雨松大神描述的清楚,该文章循序渐进,一步步引导读者去理解unirty 绘图机制,真的是没有比这个再好得了 ...

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

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

  4. Direct2D开发:MFC下从资源文件中加载位图

    转载请注明出处:http://www.cnblogs.com/ye-ming 0X01 概述: 相对于GDI处理界面,Direct2D有得天独厚的优势,下图就是Direct2D与GDI的效果对比,wi ...

  5. Direct2D开发:纹理混合

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

  6. Direct2D开发:从资源加载位图

    转载请注明出处:http://www.cnblogs.com/Ray1024 一.概述 Direct2D使用Windows图像处理组件 (WIC) 来加载位图.从文件加载位图的方法很简单,而且网上的教 ...

  7. Direct2D 几何图形绘制基础

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

  8. 【Direct2D开发】 通过操作像素实现纹理混合

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

  9. 使用Qt开发绘制多个设备的流量曲线图(附带项目图)

    一.说明: 在实际项目中,主要是使用Qt开发CS程序,当然主要是客户端.公司项目中有这个需求是实时显示多个设备的流量曲线图,设备将流量信息发给服务端,服务端再将信息通过Socket发给Qt客户端,Qt ...

随机推荐

  1. 如何扩展 Azure 资源组中虚拟机的 OS 驱动器

    概述 在资源组中通过从 Azure 应用商店部署映像来创建新的虚拟机 (VM) 时,默认的 OS 驱动器空间为 127 GB. 尽管可以将数据磁盘添加到 VM(数量取决于所选择的 SKU),并且我们建 ...

  2. EntityFramework Code-First 简易教程(一)

    前言:学习了EF框架这么久,还没有好好总结一番,正好遇到一国外的网站,发现不错,随即翻译过来,一是让自己复习一遍,二是供广大初学者学习,翻译过程中加入了一些自己的理解,如有错误,还请指出,多谢多谢.好 ...

  3. .Net 环境

    更多系统版本下载:https://www.microsoft.com/net/download VSCode :https://code.visualstudio.com/

  4. python set集合一些基本方法

    set集合是一个无序且不重复的元素集合 这个数据类型没有重复的,而且也没有顺序 一些基本的方法: 添加元素 s1 = {11, 22, 33} s1.add(123)#添加一个新的元素 print(s ...

  5. Python实例---爬去酷狗音乐

    项目一:获取酷狗TOP 100 http://www.kugou.com/yy/rank/home/1-8888.html 排名 文件&&歌手 时长 效果: 附源码: import t ...

  6. 【转】MySQL双主一致性架构优化

    [原文]https://www.toutiao.com/i6594414914838725133/ 一.双主保证高可用 MySQL数据库集群常使用一主多从,主从同步,读写分离的方式来扩充数据库的读性能 ...

  7. [日常] HEOI 2019 退役记

    HEOI 2019 退役记 先开坑 坐等AFO 啥时候想起来就更一点(咕咕咕) Day 0 早上打了个LCT, 打完一遍过编译一遍AC...(看来不考这玩意了) 然后进行了一些精神文明建设活动奶了一口 ...

  8. UI中新增一个右击按钮的过程

    1.首先给出增加之后的成品 点击后的界面 3.需要增加的部分 新增一个类:DiglogAddUser  用于操作用户填写的数据,写入数据库等操作 3.1首先在资源文件中定义窗口代号 3.2 枚举出该代 ...

  9. Android 打造属于自己的照片选择器

    前言 在做第一个项目时照片选择器使用了开源的PhotoPicker 渐渐无法满足需求,就想着打造一款属于自己的照片选择器. 花了一周的时间完成了该项目,其实代码有一大半并非自己写的,在阅读PhotoP ...

  10. JS 点击元素发ajax请求 打开一个新窗口

    JS 点击元素发ajax请求 打开一个新窗口 经常在项目中会碰到这样的需求,点击某个元素后,需要发ajax请求,请求成功以后,开发需要把链接传给前端(或者说请求成功后打开新窗口),前端需要通过新窗口打 ...