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

博客园中的高手还是有不少的,在写本系列教程的过程中,也会把碰到的问题或疑惑一一贴出来,期待高手的解答。以使得大家共同提高。

什么是Direct2D

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

Direct2D运行需求

要开发和使用Direct2D程序,系统必须是Windows 7,Windows Vista SP2, Windows Server 2008 R2或者Windows Server 2008 SP2,这样的系统需求无疑会稍稍阻碍Direct2D前进的步伐,虽然Vista和Windows 7已经推出有一段时间了,但是不可否认的是,仍然有很多人在使用XP系统。甚至是Win2K。但是新技术的普及是不可阻碍的,相信不久的将来,Direct2D将会成为2D图形世界的主流。

VS2010下的Direct2D的运行库

首先在Windows® API Code Pack for Microsoft® .NET Framework上下载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开发了。

下面是用VB2010写的Direct2D的示例类。

 
Imports Microsoft.WindowsAPICodePack.DirectX

Public Class clsDirect2DSample
    Private _d2DFactory As Direct2D1.D2DFactory
    Private _renderTarget As Direct2D1.RenderTarget

Public Sub New()
        _d2DFactory = Direct2D1.D2DFactory.CreateFactory()
    End Sub

Public Sub CreateDeviceResource(Target As Control)
        If _renderTarget Is Nothing Then
            _renderTarget = _d2DFactory.CreateHwndRenderTarget( _
                                                      New Direct2D1.RenderTargetProperties, _
                                                      New Direct2D1.HwndRenderTargetProperties( _
                                                                            Target.Handle, _
                                                                            New Direct2D1.SizeU(Target.Width, Target.Height), _
                                                                            Direct2D1.PresentOptions.None) _
                                                      )
        End If
    End Sub

Public Sub Render()
        If Not _renderTarget Is Nothing Then
            _renderTarget.BeginDraw()

Dim E As New Direct2D1.Ellipse(New Direct2D1.Point2F(50, 50), 30, 40)
            Dim B As Direct2D1.SolidColorBrush = _renderTarget.CreateSolidColorBrush(New Direct2D1.ColorF(0, 1, 0))
            _renderTarget.DrawEllipse(E, B, 4)

_renderTarget.EndDraw()
        End If
    End Sub
End Class

首先引入Microsoft.WindowsAPICodePack.DirectX命名空间,实际上还可以更进一步引入Direct2D1命名空间。只是为了区分某些类是在Direct2D下还是在原本的System下,没有引入Direct2D1命名空间。凡是在类前有Direct2D1前缀的说明该类是在Direct2D1命名空间下。

从上面的代码可以看出,要想使用Direct2D,得分下面几步走

1、创建D2DFactory,相当于Direct2D的总管类,必须首先被创建。在类的初始化函数中,用CreateFactory函数创建D2DFactory。该函数有3个重载方式,在以后的文章有机会再详细介绍

2、创建RenderTarget,相当于GDI+中的Graphics类,只有在创建后,才能进行后面的绘图操作。在本例中,用D2DFactory类的CreateHwndRenderTarget方法创建一个和指定句柄Hwnd绑定的RenderTarget。在该方法中有两个参数:RenderTargetProperties类,设置RenderTarget的一些属性(DPI等,在该类重载初始化函数中可以设置);HwndRenderTargetProperties类设置绑定的Hwnd的属性(Hwnd、宽、高等属性)

3、在完成上面两步后,可以开始绘图操作了。为了演示方便,把所有的绘图操作放在Render函数中。在Render函数中,先调用RenderTarget类的BeginDraw方法,表示要开始绘图了,再调用RenderTarget类的EndDraw方法表示绘图结束。Direct2D会把结果绘制到绑定的设备上

本例中,在Render函数中,先创建了一个Ellipse对象(椭圆),再创建一个SolidColorBrush对象(纯色笔刷),然后用RenderTarget类的DrawEllipse方法绘制一个椭圆。三个参数分别表示:椭圆、笔刷、线宽。

同时,在WinForm中,有下面的代码。把Panel1作为绑定的控件,传给示例类,并在该空间的Paint事件中调用示例类的Render方法

Public Class Form1
    Private _D As clsDirect2DSample

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        _D = New clsDirect2DSample
        _D.CreateDeviceResource(Me.Panel1)
    End Sub

Private Sub Panel1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Panel1.Paint
        _D.Render()
    End Sub
End Class

下图是程序运行的结果

在Windows API Code Pack的官网上,有Windows API Code Pack的Visual Basic的示例代码,只不过比较简单,而且是WPF的示例代码。有兴趣的可以去看看。

注意:如果直接运行的话,会出现红色大叉,表示运行错误。在项目属性中勾选调试中的“启用非托管代码调试”。会出现下面的对话框

在网友Launcher提示下,按照“混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。”一文中给出的解决方案,解决上面的错误。

解决方案是:在项目根目录下,新建app.config文件,并包含到项目中,在其中打上如下的内容

 
<?xml version="1.0"?>
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <supportedRuntime version="v4.0" sku = ".NETFramework,Version=v4.0"/>
    <supportedRuntime version="v2.0.50727"/>
  </startup>
</configuration>

接下来,把调试中遇到的三个问题写在下方。希望网友不吝赐教

问题一:引入64位的DLL,在运行时会出错。

在引入64位的DLL后,运行的时候就会出错。是在新建项目的时候,有什么设置不对么?之前的MediaInfo的64位DLL也是同样的问题。机器和操作系统都是64位的。

问题二:在窗口界面出现后,用别的窗口覆盖一下再显示,等于重新调用了一次Render。可是第二次的效果图和第一次的效果相差好多,锯齿明显了很多。在Render函数中,并没写设置锯齿的代码,为何同样的代码两次执行的效果不一致。下图是第二次的效果图。(可是如果第一次效果图出来后,最小化窗口,再恢复,也等于调用一次Render函数,效果还是和原来一样好)

问题三:在首次运行的时候,会弹出对话框,找寻h文件(或者是cpp文件),没找到会直接报错。此时,到Debug目录下,运行一遍程序后,上述的现象消失了。后面在多次运行,也不会问询文件了

Direct2D教程I——简介及首个例子的更多相关文章

  1. Direct2D教程VIII——几何(Geometry)对象的运算,本系列的终结篇

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

  2. Direct2D教程VII——变换几何(TransformedGeometry)对象

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

  3. Direct2D教程VI——转换(Transform)

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

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

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

  5. Direct2D教程II——绘制基本图形和线型(StrokeStyle)的设置详解

    目前,在博客园上,相对写得比较好的两个关于Direct2D的教程系列,分别是万一的Direct2D系列和zdd的Direct2D系列.有兴趣的网友可以去看看.本系列也是介绍Direct2D的教程,是基 ...

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

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

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

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

  8. Node.js 教程 01 - 简介、安装及配置

    系列目录: Node.js 教程 01 - 简介.安装及配置 Node.js 教程 02 - 经典的Hello World Node.js 教程 03 - 创建HTTP服务器 Node.js 教程 0 ...

  9. SharpDX之Direct2D教程II——加载位图文件和保存位图文件

    本系列文章目录: SharpDX之Direct2D教程I——简单示例和Color(颜色) 绘制位图是绘制操作的不可缺少的一部分.在Direct2D中绘制位图,必须先利用WIC组件将位图加载到内存中,再 ...

随机推荐

  1. CentOS7中配置vsftpd

    1.yum -y install vsftpd  安装vsftpd 2.配置vsftpd的配置文件(/etc/vsftpd/vsftpd.conf)主要修改以下配置内容 #不允许匿名访问 anonym ...

  2. 定时任务 Wpf.Quartz.Demo.1

    Quartz 是个开源的作业调度框架. 安装:Install-Package Quartz 官网文档地址:https://www.quartz-scheduler.net/documentation/ ...

  3. Entity Framework Core 生成跟踪列-阴影属性

    摘自:https://www.cnblogs.com/tdfblog/p/entity-framework-core-generate-tracking-columns.html Ef Core 官方 ...

  4. 【js】关于正则表达式

    正则表达式描述了字符的模式对象 语法: var patt=new RegExp(pattern,modifiers); 或更简单的方法 var patt=/pattern/modifiers; 模式描 ...

  5. 【BZOJ4755】 [Jsoi2016]扭动的回文串

    BZOJ4755 [Jsoi2016]扭动的回文串 Solution 考虑对于他给出的 A中的一个回文串: B中的一个回文串: 或者某一个回文的扭动字符串S(i,j,k) 这样子几个限制,我们1,2就 ...

  6. tcp server

    SO_REUSEADDR Ignore SIGPIPE TCP_NODELAY TCP_QUICKACK

  7. PICE(1):Programming In Clustered Environment - 集群环境内编程模式

    首先声明:标题上的所谓编程模式是我个人考虑在集群环境下跨节点(jvm)的流程控制编程模式,纯粹按实际需要构想,没什么理论支持.在5月份的深圳scala meetup上我分享了有关集群环境下的编程模式思 ...

  8. Elasticsearch集群搭建及使用Java客户端对数据存储和查询

    本次博文发两块,前部分是怎样搭建一个Elastic集群,后半部分是基于Java对数据进行写入和聚合统计. 一.Elastic集群搭建 1. 环境准备. 该集群环境基于VMware虚拟机.CentOS ...

  9. python学习笔记12-深浅拷贝

    以上为浅拷贝. .copy()函数 赋值:数据完全共享(=赋值是在内存中指向同一个对象,如果是可变(mutable)类型,比如列表,修改其中一个,另一个必定改变 如果是不可变类型(immutable) ...

  10. iOS-贝塞尔连续曲线

    一个曲线 UIColor *color = [UIColor redColor]; [color set]; UIBezierPath *path = [UIBezierPath bezierPath ...