博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Direct2D教程I——简介及首个例子
阅读量:5100 次
发布时间:2019-06-13

本文共 4249 字,大约阅读时间需要 14 分钟。

原文:

在博客园里,系统的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 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的示例代码。有兴趣的可以去看看。

 

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

在网友提示下,按照“”一文中给出的解决方案,解决上面的错误。

解决方案是:在项目根目录下,新建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目录下,运行一遍程序后,上述的现象消失了。后面在多次运行,也不会问询文件了

posted on
2019-05-05 09:16 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/10811129.html

你可能感兴趣的文章
Web消息主体风格(Message Body Style)
查看>>
eclipse- 智能提示设置
查看>>
回调函数实例——数学计算
查看>>
C#文件路径乱码
查看>>
俞伯牙摔琴谢知音的故事
查看>>
【简单dp】2080->最长公共子序列问题 动态规划
查看>>
数据库隔离级别
查看>>
C - Bear and Five Cards
查看>>
招聘工作告一段落
查看>>
druid数据源的加密解密工具
查看>>
swfupload详解
查看>>
python-微博模拟登陆
查看>>
Python【11】【前端编程】- HTML基础
查看>>
nump库的简单函数介绍
查看>>
好程序员大数据点睛:Hadoop基础篇
查看>>
JVM内存模型和GC机制
查看>>
201571030323/201571030334《小学生四则运算练习软件需求说明》结对项目报告
查看>>
SequenceFile介绍
查看>>
安卓 代码混淆与打包
查看>>
AT&T汇编语言及其寻址方式
查看>>