GDI+的替代者—D2D

[C#] Direct2D 学习笔记 (一) 写在前面:最近要做一个有关于地图的项目[C#],开始选择 GDI+ 作图,不知是算法问题还是 GDI+ 本身问题,加载非常慢而且拖动各种闪烁。迫于无奈最终放弃了 GDI+ 方式而尝试 Direct2D。但是让我意外的是网上有关 Direct2D 的教程很少,而且为数不多的教程中大多数是用 C++写的(据说是因为效率高),少部分是用VB.NET ,用 C# 的几乎没有(我是真的没找到)。最终我选择了 阅读详情

Winform中的2D绘图,以前用的都是GDI+。在简单应用环境下,如果不在乎速度,GDI+可以表现的很好。机缘巧合,前段时间做了一个简单的3D程序,使用的是C#托管 + DirectX9 SDK,平台是Win7 + VS2012。 项目做完以后,回顾发现,其实也可以使用directX11的Direct2D来进行2D绘图,这样可以尽量使用硬件加速,尽量解放CPU,使程序可以应用于更多场合。

Direct2D的理想环境是MFC/C++;如今的我只有在编写驱动程序时会用C++,对于已经习惯使用C#编写Winform的我来说,使用MFC开发Direct2D不是不可以,但是毕竟抛开MFC已经很久了(那还是VisualC++5.0时的回忆)。。。

在C#中使用Direct2D,目前看来,最合适的工具就是SharpDx,sdx可以说是目前对DirectX的最好封装,而且免费;其最大的缺点是,可以利用的文档实在太少了。闲话少叙,下面就从SharpDx开始:


一、首先从官网下载sdx(我用的时基于Desktop的应用),找到那一堆dll

二、建立一个新工程,本例是创建一个基于SharpDx的Progress的控件。

注:我使用的sdx是3.02版本,新建的c#工程需要定义为.Net FrameWork 4.5

0,准备工作:sdx中,无法使用C#的Color,Rectangle。。。因此需要做一个转换类

    
    public class dxc
    {
        public static SharpDX.Mathematics.Interop.RawColor4 ToColor4(Color cor)
        {
            return new SharpDX.Mathematics.Interop.RawColor4((float)cor.R / 256f, (float)cor.G / 256f, (float)cor.B / 256f, (float)cor.A / 256f);
        }

        public static SharpDX.Mathematics.Interop.RawRectangle ToRect(Rectangle rect)
        {
            return new SharpDX.Mathematics.Interop.RawRectangle(rect.Left, rect.Top, rect.Right, rect.Bottom);
        }

        public static SharpDX.Mathematics.Interop.RawRectangleF ToRectF(RectangleF rect)
        {
            return new SharpDX.Mathematics.Interop.RawRectangleF(rect.Left, rect.Top, rect.Right, rect.Bottom);
        }
   }
sdx中使用的Color,Rectanglef等,大都在SharpDX.Mathematics.Interop空间中,上面dxc中静态函数的作用就是做最基本的转换。
在sdx中,颜色RawColor4的定义是R/G/B/A,各个分量的取值是0~1

在sdx中,RawRectangleF使用的比较多。


1,新建一个基于Control的类

[ToolboxItem(true), ToolboxBitmap(typeof(System.Windows.Forms.ProgressBar))]
public class dxProgressBar : Control
        
2,添加属性

     
        int _pValue = 0;
        public int Value
        {
            get { return _pValue; }
            set
            {
                _pValue = value;
                if (_pValue > 100) _pValue = 100;
                if (_pValue < 0) _pValue = 0;
                this.Refresh();
            }
        }

        Color _pBorderCor = Color.Black;
        public Color BorderColor
        {
            get { return _pBorderCor; }
            set
            {
                _pBorderCor = value;
                Refresh();
            }
        }

        Color _pTextColor = Color.Blue;
        public Color TextColor
        {
            get { return _pTextColor; }
            set
            {
                _pTextColor = value;
                Refresh();
            }
        }

3,构造函数 

   
        public dxProgressBar()
        {
            InitD2D();

            this.SizeChanged+=dxProgressBar_SizeChanged;
        }

initD2D的作用是初始化sdx设备,后面有它的函数原型。


三、下面是绘图相关处理

1,添加引用

using SharpDX.DXGI;
using SharpDX.Direct2D1;
using SharpDX.Mathematics.Interop;
using SharpDX.DirectWrite;
using AlphaMode = SharpDX.Direct2D1.AlphaMode;
using DxFactory = SharpDX.Direct2D1.Factory;
using TxFactory = SharpDX.DirectWrite.Factory;
2,添加变量声明


        DxFactory dxFactory;
        WindowRenderTarget dxTarget;
        PixelFormat pixelFormat = new PixelFormat(Format.Unknown, AlphaMode.Premultiplied);
        SolidColorBrush dxBorderBrush;
        SolidColorBrush dxValueBruseh;
        RawRectangleF dxBorderRectf;
        RawRectangleF dxValueRectf;

        TxFactory txFactory;
        TextFormat txFormat;
        TextLayout txLayout;
        SolidColorBrush txtBrush;

本例中,用于绘图的资源、变量都使用dx开头;而用于绘制文本的都使用 tx开头。


3,变量初始化函数


        private void InitD2D()
        {
            dxFactory = new DxFactory(SharpDX.Direct2D1.FactoryType.SingleThreaded);

            HwndRenderTargetProperties properties = new HwndRenderTargetProperties();
            properties.Hwnd = this.Handle;
            properties.PixelSize = new SharpDX.Size2(this.Width, this.Height);
            properties.PresentOptions = PresentOptions.None;

            dxTarget = new WindowRenderTarget(dxFactory, new RenderTargetProperties(pixelFormat), properties);
            dxTarget.AntialiasMode = AntialiasMode.PerPrimitive;
            dxTarget.TextAntialiasMode = SharpDX.Direct2D1.TextAntialiasMode.Cleartype;

            txFactory = new TxFactory();
            txtBrush = new SolidColorBrush(dxTarget, dxc.ToColor4(_pTextColor));
            txFormat = new TextFormat(txFactory, this.Font.Name, this.Font.Size) { TextAlignment = TextAlignment.Center, ParagraphAlignment = ParagraphAlignment.Center };
        }


Direct2D1.Factory可以声明单线程或者多线程。

WindowRenderTarget 是要绘制图像的目标。

SolidColorBrush 是画笔,Direct2D不使用Pen,它同样使用画笔来绘制轮廓。

TxFactory、TextFormat、TextLayout等,用于绘制文本。


每次控件大小变更,则重新分配资源


        int px, py;
        private void dxProgressBar_SizeChanged(object sender, EventArgs e)
        {
            InitD2D();
            Rectangle _txRect = this.ClientRectangle;
            _txRect.Inflate(-1, -1);
            dxBorderRectf = dxc.ToRectF(_txRect);

            Refresh();
        }

dxBorderRectf是控件的轮廓区域。


4,渲染

      
        private void Render()
        {
            dxTarget.Clear(dxc.ToColor4(this.BackColor));

            dxBorderBrush = new SolidColorBrush(dxTarget, dxc.ToColor4(_pBorderCor));
            dxTarget.DrawRectangle(dxBorderRectf, dxBorderBrush, 2);

            px = Width * _pValue / 100;
            py = this.Height-2;

            dxValueRectf = new RawRectangleF(2, 2, px, py);
            dxValueBruseh = new SolidColorBrush(dxTarget, dxc.ToColor4(ForeColor));
            dxTarget.FillRectangle(dxValueRectf, dxValueBruseh);
            
            txLayout = new TextLayout(txFactory, _pValue.ToString("F2") + "%", txFormat, 60, 25);
            dxTarget.DrawText(_pValue.ToString("F2") + "%", txFormat, dxBorderRectf, txtBrush, DrawTextOptions.Clip);
        }


Render函数,首先清空绘图区域;初始化画笔,绘制外形轮廓;计算进度条举行区域,并绘制当前进度;打印当前进度值。


5,用OnPaint对控件绘图

        protected override void OnPaint(PaintEventArgs e)
        {
            //base.OnPaint(e);
            dxTarget.BeginDraw();
            Render();
            dxTarget.EndDraw();
        }

使用sdx绘图,都要以BeginDraw开始,以EndDraw结束,这个跟D3D很像。

sdx中的资源,在整个程序运行周期中,都应该尽量保留,以节省资源。


下面是运行结果:


Windows 2D 绘图 (GDI, GDI+, Direct2D) Windows 2D 绘图GDIGDI 函数GDI+GDI 和 GDI+ 的区别GDI+ 新特性Direct2D视觉效果demo GDI GDI 是 Graphics Device Interface 的缩写,含义是图形设备接口,它的主要任务是负责系统与绘图程序之间的信息交换,处理所有 Windows 程序的图形输出。 在 Windows 操作系统下,绝大多数具备图形界面的应用程序都离不开 GDI... 阅读详情

相关推荐

D2D引擎与GDI\GDI+绘制效果对比

本例主要是对比D2D和GDI在绘制文字、线条的区别,以及D2D与GDI+在绘制图片时的区别。 D2D是基于COM组件开发的,使用前的CoInitialize(NULL)是必须的;另外,GDI+的初始化GdiplusStartup()也别忘了。 废话少说,完整代码如下:// D2DDemo.cpp : 定义应用程序的入口点。 // #include "stdafx.h" #include "D

https://github.com/JelinYao 1万+

C# 从零开始写 SharpDx 应用 初始化dx修改颜色

本文来告诉大家如何在上一篇博客创建的窗口里面使用 Sharpdx 初始化,然后设置窗口颜色

lindexi 6824

从GDI到Direct2D:基本准备

最近在做个游戏,因为不能用游戏引擎,所以一开始就选了MFC+GDI的组合,毕竟CImage类是相当好用的,结果发现游戏竟然在还没有加什么功能的时候就只能跑到30帧出头,我觉得有点悬,将来如果加上更多的功能的话,一旦卡到30帧以下就没法忍了。所以我去学了一下Direct2D,这个传说当中的GDI替代品。网上现在Direct2D的资料不是很多,其中我感觉MSDN的几个样例比较适合新手入门,上面的例子都是

暗黑ZX Cyberwind 3362

SharpDX - 高性能的.NET DirectX API库

SharpDX - 高性能的.NET DirectX API库 项目地址:https://gitcode.com/gh_mirrors/sh/SharpDX 是一个开源的.NET库,用于访问DirectX API,包括Direct3D 11、Direct2D 1.1、DirectWrite、XInput、Windows Media Foundation等组件。它为.NET开发人员提供了一种简单而强...

gitblog_00076的博客 1734

从GDI到Direct2D:贴图

距离上一篇文章更新已经很长时间了,那个游戏也做完了,能跑起来,联网效果也很好(没错那是一个网络游戏),有时间的话也会考虑把怎么做一个稍具规模的游戏的笔记贴出来吧,这里我们讲怎么用Direct2D贴图。GDI里面,有一个类叫CImage,特别方便,想要读什么图片只需要Load一下,然后想画的时候,只需要说一句some_image.Draw(pDC, ...)就可以了,然而可惜的是D2D里面没有那么好用

暗黑ZX Cyberwind 2455

Direct2D 第1篇 最简单的D2D程序

编译之前,得先安装DirectX SDK #include #include #include #include #pragma comment(lib, "dwrite.lib") #pragma comment(lib, "d2d1.lib") HINSTANCE g_hinst; HWND g_hwnd; ID2D1Factory * g_factory

ubuntu_ai 3355

GDI/GDI+/D2D/D3D

原文链接 : 2D Drawing APIs in Windows     在 Windows 7 操作系统中,微软花费了很大的力气构建了一套新的 2D 绘图 API。我们称之为 Direct2D ,隶属于 DirectX 家族。这个 API 的开发填补了 Windows 图形平台的一些缺陷。其中非常重要的一点就是普通的 2D 程序渲染不再缺乏硬件加速。而在 Windows Vista 中,

jinvmen的博客 1万+

从GDI到Direct2D:Windows 2D图形API进化史与迁移指南

本文详细解析了Windows 2D图形API从GDI到Direct2D的技术演进历程,重点对比了三代API的架构差异与性能表现。通过代码示例和实测数据,展示了Direct2D在硬件加速、抗锯齿支持等方面的优势,并为开发者提供了从传统GDI迁移到现代Direct2D的实用策略和最佳实践。

weixin_30374009的博客 568

使用GDI/GDI+绘制到D3D9缓冲区的方法

这个其实是3D绘图里嵌入2D绘图的传统方式。 D3D9直接使用GDI/GDI+就可以画图,只不过需要额外的设置,而且只支持RGB和XRGB,不支持ARGB。因此这种方法比较适合合成UI元素和不透明的纹理贴图,不适合将要进行AlphaBlend操作的纹理贴图。ARGB贴图的合成要通过手动上传Gdiplus::Bitmap来实现。 使用GDI+画图的步骤: 创建设备dev时,需要pp->F...

萧戈的专栏 1660

从GDI到Direct2D:Windows 2D绘图技术演进史与现代化迁移指南

本文详细解析了Windows平台2D绘图技术从GDI到Direct2D的演进历程,包括GDI、GDI+和Direct2D的核心特性与性能对比。针对开发者提供从传统GDI向现代Direct2D迁移的实用指南,涵盖架构改造、绘图操作对照及性能优化技巧,帮助实现高性能图形应用的现代化升级。

weixin_29243279的博客 204

D2D D3D12 渲染视频帧思路及实现

写在之前耗时2个月,写完公司的音视频处理系统。对于整个音视频处理有了基本的了解。个人感觉最坑的地方有三: 编解码 音视频录制的同步 视频预览渲染(视频帧的渲染) 由于在以后要支持同时多路1080P录制及预览,所以对于性能的要求也是非常高的。虽然目前实现是分两步走,先录制再处理,但如果能做到一步到位就非常好了。有空再去优化整个项目。渲染选择API对于视频的渲染来说,已经去世的雷博给了一个DEMO。其中

zjjzhaohang的博客 7620

Direct2D 和 GDI 互操作性概述

必备条件将 Direct2D 内容绘制到 GDI 设备上下文ID2D1DCRenderTargets、GDI 转换以及从右向左书写语言版本的 Windows将 GDI 内容绘制到与 Direct2D GDI 兼容的呈现器目标相关主题 必备条件 此概述假设您熟悉基本的 Direct2D 绘制操作。有关教程,请参见 Direct2D 快速入门。它还假设您熟悉 GDI 绘制操作。 将

jinvmen的博客 4410

WIN10系统加载动画模块 二次优化,GDI+D2D 可快速调用-易语言

二次修改,支持WINXP下运行, 增加关闭命令

Direct2D开发:Direct2D 和 GDI 互操作性概述

本主题说明如何结合使用 Direct2D 和 GDI(可能为英文网页)。有两种方法可以结合使用 Direct2D 和 GDI:您可以将 GDI 内容写入与 Direct2D GDI 兼容的呈现器目标,也可以将 Direct2D 内容写入 GDI 设备上下文 (DC) 0X01 将Direct2D内容绘制到GDI设备上下文:   要将 Direct2D 内容绘制到 GDI DC,可以使用 ...

heshaai6843的博客 1343

【原创】SharpDX第一个Winform窗口

第一个SharpDX的Winform窗口,渲染在Panel中。 使用的非原有例子中的自带窗口。

C# 从零开始写 SharpDx 应用 初始化dx修改颜色 1.1

本文来告诉大家如何在上一篇博客创建的窗口里面使用 Sharpdx 初始化,然后设置窗口颜色 这是文章的代码

DirectX12(D3D12)基础教程(十三)——D2D、DWrite On D3D12与文字输出

1、 前言   在经过了前面一系列章节的“狂轰滥炸”式的学习之后,如果你现在跟进到了这里,那么请为自己点个赞先!   从本章开始,教程内容都会开始使用Markdown方式进行发布。一方面主要是为了练习Markdown编辑器的使用;另一方面Markdown目前已经成为比较流程的程序文档的编辑方式,我也来跟跟潮流,也是让大家习惯Markdown。还有就是Markdown的公式编辑比较简洁,后续的文章中...

Gamebaby Rock Sun的博客 7421

k3s快速搭建k8s集群环境

k8s 搭建方式有多种,如果你是内网环境,希望占用服务器资源少或是边缘系统(如ARM系统),强烈推荐您使用 k3s进行安装 目录k3s 简介k3s架构中文官方文档三台服务器快速搭建k8s集群安装说明步骤1 修改主机名,保持唯一步骤2 安装docker步骤3 安装master节点步骤4 安装worker节点加入集群步骤5 查看集群步骤6 部署 k8s仪表盘 dashboard k3s 简介 轻量级 Kubernetes。安装简单,内存只有一半,所有的二进制都不到 100MB K3s 是一个完全符合 Ku.

gzt19881123的专栏 2445

Direct2D教程(一)Direct2D已经来了,谁是GDI的终结者?

什么是Direct2D 一言以蔽之,就是Windows 7平台上的一个2D图形API,可以提供高性能,高质量的2D渲染。大多数人对Direct2D可能都比较陌生,以至于我之前在论坛上提到这个词的时候,有人竟然说你是不是写错了?可能大家比较熟悉的是Direct3D,因为D3D已经是当前游戏界的主流应用。在过去,3D世界是OpenGL与DirectX二分天下,但是由于OpenGL发展十分滞后,而且没...

weixin_34233421的博客 767

STM32进入HardFault_Handler时,如何找到问题所在?

当STM32进入HardFault_Handler时,定位问题发生的点

m0_60831979的博客 2150

AD20 Channel-Offset Error 解决办法

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言AD20 PCB相同电路模块ROOM格式复用时出现 Channel-Offset Error 解决办法一、问题现象二、解决办法 前言 AD20 PCB相同电路模块ROOM格式复用时出现 Channel-Offset Error 解决办法 一、问题现象 我们经常在使用Room格式快速布局相同模块电路时出现以下问题, 二、解决办法 相同模块电路PCB布局复制的过程网上有很多,这里不再做赘述,步骤都差不多,只说问题根源; 1:.

m0_47201213的博客 7624
上一篇: Using Directx In VS2012 With CS
下一篇: 打印字体
WavesLine
博客等级 码龄12年 18粉丝 58原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值