[C#] Direct2D 学习笔记 (一)vb.net转换为c#

来源:互联网 发布:lua调用linux c库 编辑:程序博客网 时间:2024/06/04 01:21
   写在前面:最近要做一个有关于地图的项目[C#],开始选择 GDI+ 作图,不知是算法问题还是 GDI+ 本身问题,加载非常慢而且拖动各种闪烁。迫于无奈最终放弃了 GDI+ 方式而尝试 Direct2D。但是让我意外的是网上有关 Direct2D 的教程很少,而且为数不多的教程中大多数是用 C++写的(据说是因为效率高),少部分是用VB.NET ,用 C# 的几乎没有(我是真的没找到)。最终我选择了一个VB.NET的教程为蓝本进行学习,将他的 VB 代码转化成 C# 代码。(之前自学过一点C++和VB,也多亏这点基础我还能看懂)

一、什么是Direct2D

一言以蔽之,就是Windows 7平台上的一个2D图形API,可以提供高性能,高质量的2D渲染。大多数人对Direct2D可能都比较陌生,以至于我之前在论坛上提到这个词的时候,有人竟然说你是不是写错了?可能大家比较熟悉的是Direct3D,因为D3D已经是当前游戏界的主流应用。在过去,3D世界是OpenGL与DirectX二分天下,但是由于OpenGL发展十分滞后,而且没有一个像微软这样强大的后台支柱,所以逐渐被DirectX所超越。回过头来说2D,过去Windows上的2D程序还主要基于GDI和GDI+,遗憾的是这两者都是软件实现,而Direct2D则不同,它基于Direct3D,所以能够使用硬件加速功能,能更大程度的发挥硬件特性,创建高性能,高质量的2D图形,这些图形包括几何图形,如矩形,椭圆等。还有位图,文本等。

二、VS2013 的 Direct2D 运行库 
首先需要下载Windows API Code Pack 1.1.zip解压后,在\Windows API Code Pack 1.1\binaries\DirectX目录下有两个子文件夹”x64”、”x86”。分别代表着64位、32位下的运行库。 
在自己的项目中引用x86下的Microsoft.WindowsAPICodePack.DirectX.dll文件。就可以进行Direct2D开发了。

三、示例 
新建一个空的winform工程,引用dll。(引用x86下的dll) 
添加如下命名空间:

using Microsoft.WindowsAPICodePack.DirectX;using Microsoft.WindowsAPICodePack.DirectX.Direct2D1;using Microsoft.WindowsAPICodePack.DirectX.Graphics;
  • 1
  • 2
  • 3

在Form.cs里的namespace xxxx里添加如下类:

public class clsDirect2DSample{    //D2D工厂对象,ID2D1Factory接口。    private D2DFactory _d2dFactory;    //渲染窗口,ID2D1HwndRenderTarget接口。    private RenderTarget _renderTarget;    //构造函数    public clsDirect2DSample()    {        //创建一个D2D工厂对象        _d2dFactory = D2DFactory.CreateFactory();    }    public void CreateDeviceResource(Control Target)    {        //如果_renderTarget没有初始化        if(_renderTarget==null)        {            //初始化,在_d2dFactory创建渲染缓冲区并与Target绑定             _renderTarget=_d2dFactory.CreateHwndRenderTarget(                    new RenderTargetProperties(),                    new HwndRenderTargetProperties(                        Target.Handle,                        new SizeU((uint)Target.Width,(uint)Target.Height),                        PresentOptions.None                        )                        );        }    }    public void Render()    {        if(_renderTarget!=null)        {            //开始绘制            _renderTarget.BeginDraw();            //椭圆            Ellipse E = new Ellipse(new Point2F(50, 50), 30, 40);            //定义一个画刷            SolidColorBrush B = _renderTarget.CreateSolidColorBrush(                    new Microsoft.WindowsAPICodePack.DirectX.Direct2D1.ColorF(0, 1, 0));            //将椭圆绘制在渲染缓冲区            _renderTarget.DrawEllipse(E, B, 4);            //结束绘制            _renderTarget.EndDraw();        }    } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

在窗体上放置一个名称为:panel1的panel控件 
在窗体类 Form1: Form 中生命一个全局变量:

private clsDirect2DSample _D;
  • 1

在Form1_Load函数里添加:

    _D = new clsDirect2DSample();    _D.CreateDeviceResource(this.panel1);
  • 1
  • 2

在Form1_Paint函数里添加:

    _D.Render();
  • 1

至此代码部分完成。 
启用“启用非托管代码调试”(启用本机代码调试): 
项目->xxxx属性->“调试”选项卡->勾选“启用本机代码调试”。

修改App.config内容如下

<?xml version="1.0" encoding="utf-8" ?><configuration>    <startup useLegacyV2RuntimeActivationPolicy="true">        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />        <supportedRuntime version="v2.0.50727"/>    </startup></configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

运行效果如图: 
这里写图片描述

上述过程就是: 
在D2D工厂对象(_d2dFactory)的渲染缓冲区/窗口(_renderTarget)中绘制图形(各种Draw方法)并最终显示(EndDraw方法)在其绑定的控件/窗体(Target)上。 
so,实际使用需要分几步走: 
1,创建D2DFactory且必须首先被创建。在类的构造函数中,用CreateFactory函数创建D2DFactory。 
2,创建RenderTarget,渲染缓冲区,相当于画板,在其上进行绘图操作。本例中用D2DFactory类的CreateHwndRenderTarget方法创建。两个参数:RenderTargetProperties类,设置RenderTarget的一些属性(DPI等,在该类重载初始化函数中可以设置);HwndRenderTargetProperties类设置绑定的Hwnd的属性(Hwnd、宽、高等属性)(这里有个疑问,为什么要传入Hwnd的宽和高?既然有句柄,这些属性应该可以直接获取到啊。。。) 
3,进行绘图,要注意绘图顺序导致的层叠关系,最后调用EndDraw显示在窗口/控件上。

后记:网上说 C# 的效率很低因此不适合做界面渲染,具体怎样我不清楚。其实对于我这种初学者来说,语言效率什么的并不重要,因为我能做到的效果还涉及不到效率问题,我仅仅要求是“能实现效果”。因此, 仅以此系列文章 献给那些和我一样的小白们。

参考:http://www.cnblogs.com/grenet/p/3249664.html 
参考:http://www.cnblogs.com/graphics/category/412802.html

原创粉丝点击