Winform中的2D绘图,以前用的都是GDI+。在简单应用环境下,如果不在乎速度,GDI+可以表现的很好。机缘巧合,前段时间做了一个简单的3D程序,使用的是C#托管 + DirectX9 SDK,平台是Win7 + VS2012。 项目做完以后,回顾发现,其实也可以使用directX11的Direct2D来进行2D绘图,这样可以尽量使用硬件加速,尽量解放CPU,使程序可以应用于更多场合。

Direct2D的理想环境是MFC/C++;如今的我只有在编写驱动程序时会用C++,对于已经习惯使用C#编写Winform的我来说,使用MFC开发Direct2D不是不可以,但是毕竟抛开MFC已经很久了(那还是VisualC++5.0时的回忆)。。。

在C#中使用Direct2D,目前看来,最合适的工具就是SharpDx,sdx可以说是目前对DirectX的最好封装,而且免费;其最大的缺点是,可以利用的文档实在太少了。闲话少叙,下面就从SharpDx开始:

一、首先从官网下载sdx(我用的时基于Desktop的应用),找到那一堆dll

二、建立一个新工程,本例是创建一个基于SharpDx的Progress的控件。

注:我使用的sdx是3.02版本,新建的c#工程需要定义为.Net FrameWork 4.5

0,准备工作:sdx中,无法使用C#的Color,Rectangle。。。因此需要做一个转换类

    
    public class dxc{public static SharpDX.Mathematics.Interop.RawColor4 ToColor4(Color cor){return new SharpDX.Mathematics.Interop.RawColor4((float)cor.R / 256f, (float)cor.G / 256f, (float)cor.B / 256f, (float)cor.A / 256f);}public static SharpDX.Mathematics.Interop.RawRectangle ToRect(Rectangle rect){return new SharpDX.Mathematics.Interop.RawRectangle(rect.Left, rect.Top, rect.Right, rect.Bottom);}public static SharpDX.Mathematics.Interop.RawRectangleF ToRectF(RectangleF rect){return new SharpDX.Mathematics.Interop.RawRectangleF(rect.Left, rect.Top, rect.Right, rect.Bottom);}}

sdx中使用的Color,Rectanglef等,大都在SharpDX.Mathematics.Interop空间中,上面dxc中静态函数的作用就是做最基本的转换。
在sdx中,颜色RawColor4的定义是R/G/B/A,各个分量的取值是0~1

在sdx中,RawRectangleF使用的比较多。

1,新建一个基于Control的类

[ToolboxItem(true), ToolboxBitmap(typeof(System.Windows.Forms.ProgressBar))]
public class dxProgressBar : Control

2,添加属性

     
        int _pValue = 0;public int Value{get { return _pValue; }set{_pValue = value;if (_pValue > 100) _pValue = 100;if (_pValue < 0) _pValue = 0;this.Refresh();}}Color _pBorderCor = Color.Black;public Color BorderColor{get { return _pBorderCor; }set{_pBorderCor = value;Refresh();}}Color _pTextColor = Color.Blue;public Color TextColor{get { return _pTextColor; }set{_pTextColor = value;Refresh();}}

3,构造函数

   
        public dxProgressBar(){InitD2D();this.SizeChanged+=dxProgressBar_SizeChanged;}

initD2D的作用是初始化sdx设备,后面有它的函数原型。

三、下面是绘图相关处理

1,添加引用

using SharpDX.DXGI;
using SharpDX.Direct2D1;
using SharpDX.Mathematics.Interop;
using SharpDX.DirectWrite;
using AlphaMode = SharpDX.Direct2D1.AlphaMode;
using DxFactory = SharpDX.Direct2D1.Factory;
using TxFactory = SharpDX.DirectWrite.Factory;

2,添加变量声明


        DxFactory dxFactory;WindowRenderTarget dxTarget;PixelFormat pixelFormat = new PixelFormat(Format.Unknown, AlphaMode.Premultiplied);SolidColorBrush dxBorderBrush;SolidColorBrush dxValueBruseh;RawRectangleF dxBorderRectf;RawRectangleF dxValueRectf;TxFactory txFactory;TextFormat txFormat;TextLayout txLayout;SolidColorBrush txtBrush;

本例中,用于绘图的资源、变量都使用dx开头;而用于绘制文本的都使用 tx开头。

3,变量初始化函数


        private void InitD2D(){dxFactory = new DxFactory(SharpDX.Direct2D1.FactoryType.SingleThreaded);HwndRenderTargetProperties properties = new HwndRenderTargetProperties();properties.Hwnd = this.Handle;properties.PixelSize = new SharpDX.Size2(this.Width, this.Height);properties.PresentOptions = PresentOptions.None;dxTarget = new WindowRenderTarget(dxFactory, new RenderTargetProperties(pixelFormat), properties);dxTarget.AntialiasMode = AntialiasMode.PerPrimitive;dxTarget.TextAntialiasMode = SharpDX.Direct2D1.TextAntialiasMode.Cleartype;txFactory = new TxFactory();txtBrush = new SolidColorBrush(dxTarget, dxc.ToColor4(_pTextColor));txFormat = new TextFormat(txFactory, this.Font.Name, this.Font.Size) { TextAlignment = TextAlignment.Center, ParagraphAlignment = ParagraphAlignment.Center };}

Direct2D1.Factory可以声明单线程或者多线程。

WindowRenderTarget 是要绘制图像的目标。

SolidColorBrush 是画笔,Direct2D不使用Pen,它同样使用画笔来绘制轮廓。

TxFactory、TextFormat、TextLayout等,用于绘制文本。

每次控件大小变更,则重新分配资源


        int px, py;private void dxProgressBar_SizeChanged(object sender, EventArgs e){InitD2D();Rectangle _txRect = this.ClientRectangle;_txRect.Inflate(-1, -1);dxBorderRectf = dxc.ToRectF(_txRect);Refresh();}

dxBorderRectf是控件的轮廓区域。

4,渲染

      
        private void Render(){dxTarget.Clear(dxc.ToColor4(this.BackColor));dxBorderBrush = new SolidColorBrush(dxTarget, dxc.ToColor4(_pBorderCor));dxTarget.DrawRectangle(dxBorderRectf, dxBorderBrush, 2);px = Width * _pValue / 100;py = this.Height-2;dxValueRectf = new RawRectangleF(2, 2, px, py);dxValueBruseh = new SolidColorBrush(dxTarget, dxc.ToColor4(ForeColor));dxTarget.FillRectangle(dxValueRectf, dxValueBruseh);txLayout = new TextLayout(txFactory, _pValue.ToString("F2") + "%", txFormat, 60, 25);dxTarget.DrawText(_pValue.ToString("F2") + "%", txFormat, dxBorderRectf, txtBrush, DrawTextOptions.Clip);}

Render函数,首先清空绘图区域;初始化画笔,绘制外形轮廓;计算进度条举行区域,并绘制当前进度;打印当前进度值。

5,用OnPaint对控件绘图


        protected override void OnPaint(PaintEventArgs e){//base.OnPaint(e);dxTarget.BeginDraw();Render();dxTarget.EndDraw();}

使用sdx绘图,都要以BeginDraw开始,以EndDraw结束,这个跟D3D很像。

sdx中的资源,在整个程序运行周期中,都应该尽量保留,以节省资源。

下面是运行结果:

GDI+的替代者—D2D相关推荐

  1. UWP 和 WPF 对比

    原文: UWP 和 WPF 对比 本文告诉大家 UWP 和 WPF 的不同. 如果在遇到技术选择或者想和小伙伴吹的时候可以让他以为自己很厉害,那么请继续看. 如果在看这文章还不知道什么是 UWP 和 ...

  2. 【转】UWP 和 WPF 对比

    本文告诉大家 UWP 和 WPF 的不同. 如果在遇到技术选择或者想和小伙伴吹的时候可以让他以为自己很厉害,那么请继续看. 如果在看这文章还不知道什么是 UWP 和 WPF 那么也没关系,下面会告诉大 ...

  3. python编写井字棋_编写井字游戏

    python编写井字棋 Programming computer games may be the most technically challenging (and possibly the bes ...

  4. D2D引擎与GDI\GDI+绘制效果对比

    本例主要是对比D2D和GDI在绘制文字.线条的区别,以及D2D与GDI+在绘制图片时的区别. D2D是基于COM组件开发的,使用前的CoInitialize(NULL)是必须的:另外,GDI+的初始化 ...

  5. GDI/GDI+/D2D/D3D

    原文链接 : 2D Drawing APIs in Windows 在 Windows 7 操作系统中,微软花费了很大的力气构建了一套新的 2D 绘图 API.我们称之为 Direct2D ,隶属于 ...

  6. GDI+编程说明及小结

    原文地址:http://blog.csdn.net/byxdaz/article/details/5972759 GDI+(Graphics Device Interface Plus图形设备接口加) ...

  7. Direct2D教程(一)Direct2D已经来了,谁是GDI的终结者?

    什么是Direct2D 一言以蔽之,就是Windows 7平台上的一个2D图形API,可以提供高性能,高质量的2D渲染.大多数人对Direct2D可能都比较陌生,以至于我之前在论坛上提到这个词的时候, ...

  8. GDI+中发生一般性错误的解决办法 from http://www.cnblogs.com/winzheng/archive/2008/12/23/1360440.html...

    GDI+中发生一般性错误的解决办法 这个错误经常发生,代码如下:    private  static  byte[] GetBytes (Image image)         {         ...

  9. VS2010 使用GDI+创建图片水印的MFC程序

    首先配置好VS2010 的GDIplus的环境: http://www.hacktea8.com/read.php?tid-1489.html 创建文件对话框的函数: [部分源码] //定义文件打开的 ...

最新文章

  1. 详解jQuery对象与DOM对象的相互转换
  2. 用SAP WebIDE将CRUD Master-Detail应用打包成Hybrid App
  3. 点分治(简要讲解 + 模板)
  4. python解析html的库_用python解析html
  5. 手机展示海报就用它 再不要羡慕别人
  6. 师范生计算机期末考试题目,2015年深圳宝安区计算机教师招聘考试试题[师范生发布]无答案...
  7. eclipse 下安装插件
  8. svnant-不可映射字符编码
  9. vue 项目中引入字体文件的正确方式~
  10. Linux程序设计第二版练习题(第五章)
  11. 计算机Excel运行环境,Excel2007免费完整版 最新电脑版
  12. 无监督降维 效果评价 trustworthiness measure
  13. 利用python进行假设假设检验
  14. multisim变压器反馈式_基于Multisim的电压串联型负反馈电路的仿真与分析
  15. 数据分析报告,就该这么写
  16. 【CAD基础】图层管理
  17. 微信小游戏 -- unhandled promise rejection 解决办法
  18. S7-1200定时器
  19. Linux系统使用教程
  20. 基于眼动跟踪的人眼兴趣点检测

热门文章

  1. 精致树叶鼠标指针(两款)
  2. 全球领先的 MySQL 数据库开发管理工具
  3. 柯尼卡美能达Konica Minolta magicolor 2300DL 打印机驱动
  4. 串联滞后校正网络的作用_串联滞后校正利用滞后网络的高频幅值
  5. gpib安装包 python_python控制gpib
  6. linux端口带卡,基于嵌入式Linux的接口转换卡设计
  7. 【论文阅读】【逐字翻译】 爱丁堡大学IEEE TPAMI 2021年最新元学习综述 《Meta-Learning in Neural Networks: A Survey》
  8. 计算机网络技术实训自我评价,计算机网络技术个人简历自我评价范文
  9. 【Windows系统】win10系统假死,窗口不能动,鼠标能动或不能动,最后蓝屏显示错误码: VIDEO_DXGKRNL_FATAL_ERROR 的解决办法
  10. 北京信息科技大学第十一届程序设计竞赛(重现赛)J andy的树被砍了