您的位置:首页 > 编程语言 > VB

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

2017-09-13 11:00 246 查看
   写在前面:最近要做一个有关于地图的项目[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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐