本文告诉大家通过 SharpDx 画出简单的 2D 界面

本文属于 SharpDx 系列 博客,建议从头开始读

本文分为两步,第一步是初始化,第二步才是画界面

初始化

先创建 RenderForm 用来显示界面,在创建的过程需要指定宽度和高度

_renderForm = new RenderForm();

_renderForm.ClientSize = new Size(Width, Height);

private const int Width = 1280;

private const int Height = 720;

在 InitializeDeviceResources 函数里面更改一些参数,用于创建资源和初始化

var backBufferDesc =

new ModeDescription(Width, Height, new Rational(60, 1), Format.R8G8B8A8_UNorm);

var swapChainDesc = new SwapChainDescription

{

BufferCount = 1,

ModeDescription = backBufferDesc,

IsWindowed = true,

OutputHandle = _renderForm.Handle,

SampleDescription = new SampleDescription(1, 0),

SwapEffect = SwapEffect.Discard,

Usage = Usage.RenderTargetOutput

};

Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.BgraSupport, swapChainDesc,

out _d3DDevice, out _swapChain);

_d3DDeviceContext = _d3DDevice.ImmediateContext;

using (var backBuffer = _swapChain.GetBackBuffer(0))

{

_renderTargetView = new RenderTargetView(_d3DDevice, backBuffer);

_viewport = new Viewport(0, 0, Width, Height);

_d3DDeviceContext.Rasterizer.SetViewport(_viewport);

}

CreateD2DRender();

上面参数和C# 从零开始写 SharpDx 应用 初始化dx修改颜色的有一些不相同,在 SwapChainDescription 里面添加了 SwapEffect 参数

在创建交换链的时候,在 Device.CreateWithSwapChain 里面修改了 DeviceCreationFlags 参数

上面内容还是在创建 3D 内容,在 DX 里面是通过一个 3D 的平面画 2D 界面

在 CreateD2DRender 方法里面才是创建 2D 的代码

想要绘制界面需要 SharpDX.Direct2D1.RenderTarget 对象,需要先创建工厂然后通过工厂和交换链拿到平面,然后将输出定向到拿到的平面

创建工厂只需要直接创建

var d2dFactory = new SharpDX.Direct2D1.Factory();

从交换链拿到平面

Texture2D backBuffer = D3D11.Resource.FromSwapChain(_swapChain, 0);

Surface surface = backBuffer.QueryInterface();

创建 RenderTarget 用于绘图

var d2dRenderTarget = new RenderTarget(d2dFactory, surface,

new RenderTargetProperties(new PixelFormat(Format.Unknown, AlphaMode.Premultiplied)));

这里 CreateD2DRender 方法代码请看下面

using DeviceContext = SharpDX.Direct2D1.DeviceContext;

using Factory = SharpDX.Direct2D1.Factory;

private void CreateD2DRender()

{

var d2dFactory = new SharpDX.Direct2D1.Factory();

Texture2D backBuffer = D3D11.Resource.FromSwapChain(_swapChain, 0);

Surface surface = backBuffer.QueryInterface();

var d2dRenderTarget = new RenderTarget(d2dFactory, surface,

new RenderTargetProperties(new PixelFormat(Format.Unknown, AlphaMode.Premultiplied)));

_d2dFactory = d2dFactory;

_d2dRenderTarget = d2dRenderTarget;

}

private Factory _d2dFactory;

private RenderTarget _d2dRenderTarget;

现在拿到了 _d2dRenderTarget 就可以用来画 2D 的界面了,开启绘制循环之后进行画界面

public void Run()

{

RenderLoop.Run(_renderForm, RenderCallback);

}

private void RenderCallback()

{

Draw();

}

private void Draw()

{

// 在这里绘制

}

下面将会告诉大家如何在 Draw 方法里面绘制界面

画界面

在 Draw 方法里面,使用下面方式画界面

private void Draw()

{

_d2dRenderTarget.BeginDraw();

// 实际画的代码

_d2dRenderTarget.EndDraw();

_swapChain.Present(1, PresentFlags.None);

}

先调用 BeginDraw 方法开启绘制,在调用 EndDraw 方法将所有绘制指令压缩处理,大部分都是直接传送到显卡渲染

然后调用交换链 _swapChain 将后台缓存和前台显示交换,这样就可以做到刷新界面

具体画的内容可以分为基础图形和 3D 绘制

在所有开始绘制之前都需要调用 BeginDraw 方法,在绘制完成之后调用 EndDraw 方法将绘制的命令处理,然后发送到显卡

画线

画线条需要传入两个点,用两个点画出一条线条,还有线条的笔刷。可选的是线条的宽度,和样式

下面代码是作为添加所有参数的例子

_d2dRenderTarget.BeginDraw();

var brush = new SolidColorBrush(_d2dRenderTarget, ColorToRaw4(Color.Bisque));

var styleProperties = new StrokeStyleProperties()

{

StartCap = CapStyle.Square,

EndCap = CapStyle.Round

};

var strokeStyle = new StrokeStyle(_d2dFactory, styleProperties);

using (strokeStyle)

using (brush)

{

_d2dRenderTarget.DrawLine(new RawVector2(10, 100), new RawVector2(100, 100),

brush, strokeWidth: 5, strokeStyle);

}

_d2dRenderTarget.EndDraw();

运行代码可以看到下面图片

这段代码写在 Draw 函数里面,在 SharpDx 里面创建的资源,例如笔画和样式等,都需要做手动的释放,这部分的写法和 WPF 不相同,需要自己关注资源的创建和释放,但是这样做才能做到更改的性能

在 StrokeStyleProperties 里面有很多有趣的参数,请大家自己玩一下

在代码里面用到 ColorToRaw4 方法,因为在 SharpDx 里面的颜色使用的范围是 0-1 而不是 System.Drawing.Color 使用 255 范围

RawColor4 ColorToRaw4(Color color)

{

const float n = 255f;

return new RawColor4(color.R / n, color.G / n, color.B / n, color.A / n);

}

通过 ColorToRaw4 方法可以转换颜色

矩形

通过 DrawRectangle 方法可以画出矩形,在矩形里面需要传入 RawRectangleF 和颜色,可选线条宽度和样式和线条相同

var brush = new SolidColorBrush(_d2dRenderTarget, ColorToRaw4(Color.Bisque));

var rect = new RawRectangleF(10, 10, 100, 100);

using (brush)

{

_d2dRenderTarget.DrawRectangle(rect, brush);

}

注意 RawRectangleF 的构造函数传入的是左上右下而不是左上角的点和宽度高度

var rect = new RawRectangleF(left: 10, top: 10, right: 100, bottom: 100);

在没有指定线条宽度是会使用 _d2dRenderTarget 的默认线条宽度,通过下面代码可以设置默认线条宽度

_d2dRenderTarget.StrokeWidth = 10;

圆角矩形可以使用 DrawRoundedRectangle 方法

var roundedRectangle = new RoundedRectangle();

roundedRectangle.Rect = rect;

roundedRectangle.RadiusX = 10;

roundedRectangle.RadiusY = 10;

_d2dRenderTarget.DrawRoundedRectangle(roundedRectangle, brush);

这里的 rect 和 brush 都是上面的代码

填充矩形使用 FillRectangle 方法,这个方法只需要传入矩形和笔刷,稍微更改上面的代码

_d2dRenderTarget.FillRectangle(rect, brush);

运行代码你可以看到一个填充的矩形

填充的圆角矩形使用 FillRoundedRectangle 方法,这个方法也不需要传入线条宽度等

_d2dRenderTarget.FillRoundedRectangle(roundedRectangle, brush);

运行上面代码,可以看到填充的圆角矩形

椭圆

画椭圆使用 DrawEllipse 方法,传入椭圆和线条颜色,可选线条宽度和样式

var brush = new SolidColorBrush(_d2dRenderTarget, ColorToRaw4(Color.Bisque));

var ellipse = new Ellipse(new RawVector2(100, 100), 10, 10);

using (brush)

{

_d2dRenderTarget.DrawEllipse(ellipse, brush);

}

运行上面代码可以看到下图

创建椭圆时传入的是圆心和两个方向的大小

填充椭圆使用 FillEllipse 方法,传入的是笔刷,不需要传入线条宽度等

var brush = new SolidColorBrush(_d2dRenderTarget, ColorToRaw4(Color.Bisque));

var ellipse = new Ellipse(new RawVector2(100, 100), 10, 10);

using (brush)

{

_d2dRenderTarget.FillEllipse(ellipse, brush);

}

使用上面代码可以填充椭圆

几何

复杂的几何可以使用 Geometry 绘制

使用 DrawGeometry 方法传入 Geometry 和颜色,可选线条相关设置

var brush = new SolidColorBrush(_d2dRenderTarget, ColorToRaw4(Color.Bisque));

var rect = new RawRectangleF(left: 10, top: 10, right: 100, bottom: 100);

Geometry geometry = new RectangleGeometry(_d2dFactory, rect);

using(geometry)

using (brush)

{

_d2dRenderTarget.DrawGeometry(geometry, brush);

}

这里的 Geometry 可选的很多,最支持定制的是 PathGeometry 方法

如使用很多代码画出线条

var geometry = new PathGeometry(_d2dFactory);

var geometrySink = geometry.Open();

geometrySink.BeginFigure(new RawVector2(10,100),FigureBegin.Filled );

geometrySink.AddLine(new RawVector2(100,100));

geometrySink.EndFigure(FigureEnd.Closed);

geometrySink.Close();

在 PathGeometry 使用 Open 方法返回 GeometrySink 可以支持很多绘制,包括组合多个几何

文字

绘制文字需要 SharpDX.DirectWrite.Factory 需要先创建才能使用,注意工厂需要只创建一次

var factory = new SharpDX.DirectWrite.Factory();

创建工厂可以用来实例文本格式

var textFormat = new TextFormat(factory, "宋体", 20);

在 TextFormat 构造函数可以传入很多参数,用于绘制

绘制文本需要使用 DrawText 方法,在这个方法传入需要绘制的字符串和文本格式,和绘制的范围和颜色

var brush = new SolidColorBrush(_d2dRenderTarget, ColorToRaw4(Color.Bisque));

var factory = new SharpDX.DirectWrite.Factory();

var textFormat = new TextFormat(factory, "宋体", 20);

var rect = new RawRectangleF(left: 10, top: 10, right: 100, bottom: 100);

using(textFormat)

using (brush)

{

_d2dRenderTarget.DrawText("林德熙是逗比", textFormat, rect, brush);

}

对于 factory 在实际项目请写在初始化的方法,而不是每次进入绘制方法的时候都创建,这个代码将会内存泄露

在画文本需要用到很多参数,用于自己定制,请小伙伴自己玩一下

有了基础的画界面就可以做出好看的界面,如何根据这些简单的方法画出好看的界面请看 WPF 源代码 从零开始写一个 UI 框架

使用 SharpDx 绘制很底层,但是绘制性能超级高

我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新

如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

2d绘制 c# dx_C# 从零开始写 SharpDx 应用 绘制基础图形相关推荐

  1. C# 从零开始写 SharpDx 应用 笔刷

    本文告诉大家如何在 SharpDx 里面使用笔刷,包括纯色笔刷.渐变笔刷和图片笔刷 本文属于 SharpDx 系列 博客,建议从头开始读 初始化 本文将会在 C# 从零开始写 SharpDx 应用 初 ...

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

    本文来告诉大家如何在上一篇博客创建的窗口里面使用 Sharpdx 初始化,然后设置窗口颜色 本文是 SharpDX 系列博客,更多博客请点击SharpDX 系列 在C# 从零开始写 SharpDx 应 ...

  3. C# 从零开始写 SharpDx 应用 画三角

    在当前的画面都是使用三角形,在开始就告诉大家如何画三角,本文告诉大家如何用像素著色器画 本文是 SharpDX 系列博客,更多博客请点击SharpDX 系列 在 C# 从零开始写 SharpDx 应用 ...

  4. 2019-8-30-C#-从零开始写-SharpDx-应用-笔刷

    title author date CreateTime categories C# 从零开始写 SharpDx 应用 笔刷 lindexi 2019-8-30 8:50:0 +0800 2019-6 ...

  5. 2018-10-20-C#-从零开始写-SharpDx-应用-初始化dx修改颜色

    title author date CreateTime categories C# 从零开始写 SharpDx 应用 初始化dx修改颜色 lindexi 2018-10-20 17:34:37 +0 ...

  6. 2018-9-30-C#-从零开始写-SharpDx-应用-画三角

    title author date CreateTime categories C# 从零开始写 SharpDx 应用 画三角 lindexi 2018-09-30 18:30:14 +0800 20 ...

  7. 从零开始写一个武侠冒险游戏-3-地图生成

    2019独角兽企业重金招聘Python工程师标准>>> 从零开始写一个武侠冒险游戏-3-地图生成 概述 前面两章我们设计了角色的状态, 绘制出了角色, 并且赋予角色动作, 现在是时候 ...

  8. 从零开始写一个武侠冒险游戏-6-用GPU提升性能(1)

    从零开始写一个武侠冒险游戏-6-用GPU提升性能(1) ----把帧动画的实现放在GPU上 作者:FreeBlues 修订记录 2016.06.19 初稿完成. 2016.08.05 增加对 XCod ...

  9. 从零开始写一个武侠冒险游戏-8-用GPU提升性能(3)

    从零开始写一个武侠冒险游戏-8-用GPU提升性能(3) ----解决因绘制雷达图导致的帧速下降问题 作者:FreeBlues 修订记录 2016.06.23 初稿完成. 2016.08.07 增加对 ...

最新文章

  1. LeetCode-175. 组合两个表(SQL语句中的LEFT JOIN)
  2. Delphi中比较两个对象是否一致及地址是否相同
  3. jira集成开发代码_7种JIRA集成可优化您的Java开发流程
  4. android设置访问internet权限
  5. php 当前linux用户权限,Linux 下用户组别权限的理解
  6. POJ 2888 Magic Bracelet ——Burnside引理
  7. 操作系统————P1 概念、功能和目标
  8. 塔菲尔曲线斜率的大小_中国第一塔,与埃菲尔铁塔齐名,到底有多强悍?
  9. primefaces_Primefaces单选按钮,复选框示例
  10. 通用权限管理系统组件 (GPM - General Permissions Manager) 中实现系统参数配置保存,附源码...
  11. C++笔记------数据类型
  12. Linux下挂载NTFS
  13. 用VB.net编写的Windows服务管理程序(堪称经典)全部源代码
  14. java放大镜_Java写的屏幕放大镜
  15. 4种方法解决鼠标反应慢(迟钝)
  16. Latex/CTeX WinEdt7.0 连续查找替换功能 “如何统计字数”
  17. 买富勒鼠标的请注意了
  18. ScreenFlow:屏幕录制软件
  19. Encyclopaedia Britannica Ultimate 2014电子版下载|大不列颠百科全书
  20. c4droid用c语言画爱心,【图片】[自学C语言第五天]发一个作品【c4droid吧】_百度贴吧...

热门文章

  1. 解救电商大促没灵感的设计师|攻略模板奉上
  2. 插画在UI的应用体验,太美好了!这样的模板让你的用户更加喜欢!
  3. TCP协议的三次握手及释放
  4. C语言以二进制形式读入文件
  5. Build-Docker-Image-from-Zero: 从零构建Docker镜像
  6. NGINX内部:我们如何设计性能和规模
  7. php采集单线程卡死,php - 为什么我这段curl采集,单线程比多线程还快?
  8. echart 三维可视化地图_Echarts百度可视化图形库
  9. python获取类的类属性_Python中如何获取类属性的列表
  10. java多元解析方程组