Direct2D教程I——简介及首个例子

简介:

在博客园里,系统的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.EventArgsHandles MyBase.Load 
        _D = New clsDirect2DSample 
        _D.CreateDeviceResource(Me.Panel1) 
    End Sub 

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

 

下图是程序运行的结果

image

 

在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函数,效果还是和原来一样好)

image

 

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


    本文转自万仓一黍博客园博客,原文链接:http://www.cnblogs.com/grenet/p/3249664.html,如需转载请自行联系原作者

相关文章
|
4月前
|
存储 SQL 关系型数据库
探秘MSSQL存储过程:功能、用法及实战案例
探秘MSSQL存储过程:功能、用法及实战案例
|
8月前
|
存储 数据可视化 Ubuntu
bcftools学习笔记丨软件简介、安装方式、使用方法、核心功能、参数解释等一文速览
bcftools学习笔记丨软件简介、安装方式、使用方法、核心功能、参数解释等一文速览
|
8月前
|
算法 数据安全/隐私保护 芯片
快速入门数字芯片设计,UCSD ECE111(十一)Project的一些注意事项
快速入门数字芯片设计,UCSD ECE111(十一)Project的一些注意事项
72 0
|
11月前
|
JSON Kubernetes Cloud Native
带你读《云原生应用开发:Operator原理与实践》——2.2.2 Client-go 主体结构
带你读《云原生应用开发:Operator原理与实践》——2.2.2 Client-go 主体结构
|
存储 Go 索引
三分钟学 Go 语言——range深度解析
三分钟学 Go 语言——range深度解析
三分钟学 Go 语言——range深度解析
|
机器学习/深度学习 存储 前端开发
【算法社区】从零开始的DS生活 轻松从0基础实现多种队列
本文详细介绍了队列的概念和性质,简要的介绍了队列ADT并附三种实现方式(链式、顺序api、顺序+动态扩容),对循环、双端、阻塞、优先级队列进行简单的应用与jdk源码分析,供读者理解与学习,适合点赞+收藏。有什么错误希望大家直接指出~
【算法社区】从零开始的DS生活 轻松从0基础实现多种队列
|
存储 安全 程序员
Libra教程之:move语言的特点和例子
Libra教程之:move语言的特点和例子
Libra教程之:move语言的特点和例子
|
搜索推荐 算法 索引
干货收藏:一文掌握十大经典排序算法(动态演示+代码)(er )
干货收藏:一文掌握十大经典排序算法(动态演示+代码)
109 0
|
Cloud Native 安全 网络架构
带你读《云原生应用开发 Operator原理与实践》第二章 Operator 原理2.2Client-go 原理(十五)
带你读《云原生应用开发 Operator原理与实践》第二章 Operator 原理2.2Client-go 原理
|
缓存 安全 Cloud Native
带你读《云原生应用开发 Operator原理与实践》第二章 Operator 原理2.2Client-go 原理(十四)
带你读《云原生应用开发 Operator原理与实践》第二章 Operator 原理2.2Client-go 原理