Direct2D教程I——简介及首个例子_weixin_33976072的博客-程序员秘密

技术标签: 操作系统  

在博客园里,系统的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

 

下图是程序运行的结果

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目录下,运行一遍程序后,上述的现象消失了。后面在多次运行,也不会问询文件了

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_33976072/article/details/85579192

智能推荐

【DG】物理DG中LNSn、NSS、NSA进程_coco3600的博客-程序员秘密

【DG】物理DG中主库的LNSn、NSS、NSA进程的比较 BLOG文档结构图 前言部分 ...

Poly-YOLO:更快,更精确的检测(主要解决Yolov3两大问题,附源代码)_计算机视觉研究院的博客-程序员秘密

关注并星标从此不迷路计算机视觉研究院公众号ID|ComputerVisionGzq学习群|扫码在主页获取加入方式论文地址:https://arxiv.org/pdf/2005.13243....

ios 请求失败封装_手把手教你封装一个简单的iOS HTTP请求_洛岗的博客-程序员秘密

前言最近在研究AFN的实现方式,发现它使用block替代了代理的方式,将各个网络请求的各个阶段都整合在一起,使得代码更加简洁易读,于是我也参照它的方式尝试用swift封装了一个基于NSURLSession的网络请求,实现了一些简单功能。知识准备在此之前有必要了解一些关于NSURLSession的相关知识,我在iOS网络-NSURLSession简单使用中简单总结了一些,更详细的资料可以看看URL ...

python 画图colorbar 颜色大全 plt.cm.get_cmap_Andrew_SJ的博客-程序员秘密

https://blog.csdn.net/Lee_Yu_Rui/article/details/107995652

iOS 应用内连接WIFI 仅限iOS 11_希望丶的博客-程序员秘密

使用场景当已知SSID和密码的情况下,在应用内切换到这个WIFI, 而不需要跳转到系统WIFI列表页面点击.引入框架1. 在 build Phass -> Link Binay With Libraries  引入框架NetworkExtension.framework2. 在Capabilities 中打开 hotspot Configuration开

基于verilog的异步FIFO设计_科研的小萌娃的博客-程序员秘密

微信公众号“FPGA科技室”本文所研究的FIFO,从硬件的观点来看,就是一块数据内存。它有两个端口,一个用来写数据,就是将数据存入FIFO;另一个用来读数据,也就是将数据从FIFO当中取出。与FIFO操作相关的有两个指针,写指针指向要写的内存部分,读指针指向要读的内存部分。FIFO控制器通过外部的读写信号控制这两个指针移动,并由此产生FIFO空信号或满信号。对于异步FIFO(当读写FIFO...

随便推点

深度学习高速路上,PaddlePaddle正在弯道超车_weixin_33686714的博客-程序员秘密

深度学习是机器学习中一种基于对数据进行表证学习的方法,近些年不断发展并广受欢迎。研究热潮的持续高涨,带来各种开源深度学习框架层出不穷,其中包括TensorFlow、Caffe、Keras、CNTK、Torch7、MXNet、Leaf、PaddlePaddle、Theano、DeepLearning4、Lasagne、Neon等,在此背景下...

Remove untracked files, stash or commit any changes, and try again_天渺工作室的博客-程序员秘密

在react 项目中暴露webpack 配置文件的时候,执行yarn run eject报错Remove untracked files, stash or commit any changes, and try again.error Command failed with exit code 1.info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.其实就是因

原生态JDBC程序问题总结_柚子君_的博客-程序员秘密

MyBatis是一个持久层的框架。持久层的框架都是对JDBC的封装。<1>对原生态JDBC程序(单独使用JDBC开发)问题总结<1.1>jdbc程序 使用jdbc查询mysql数据库中用户表的记录创建java工程,加入jar包 数据库驱动包:mysql/oracle一般需要以下七个步骤: 加载JDBC驱动;建立并获取数据库连接;创建 JDBC Statements 对象;设置SQL语句

观纪录片《定位》有感_纪录片《定位》观后感_BobYaoud的博客-程序员秘密

这里写自定义目录标题欢迎使用Markdown编辑器什么是战略定位功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入欢迎使用Markdown编辑器趁着清明假期,笔者在家看了几部纪录片,其中一部名为战略定位的纪录片,吸引了我的注意,观

懒人糖醋排骨_str_818的博客-程序员秘密

懒人糖醋排骨原料:猪小排、料酒、酱油、米醋、白糖、姜片、盐步骤:1、猪小排冼净,晾干水份备用,也可以用纸擦干2、锅内倒少量油,烧热之后,爆香姜片3、放入排骨,一直煸炒到排骨变色后,表面金黄微焦4、此时就可以放入黄金比例中的调料了,顺序是:先放一汤勺料酒→两汤勺酱油→三汤勺米醋→四汤勺白糖,炒匀5、再倒入能没过排骨的开水**(一定要没过排骨)**,调中小火焖20分钟6、20分钟后调入...

apache java下载文件,使用apache-commons-fileupload上传、下载文件_weixin_39765325的博客-程序员秘密

实现文件的上传,代码如下://服务器端保存上传文件的路径String saveDirectory = "g:\\upload\\";// 临时路径 一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录String tmpDirectory = "g:\\upload\\tmp\\";// 最多只允许在内存中存储的数据大小,单位:字节int maxPostSize = 1...

推荐文章

热门文章

相关标签