C# 二维绘图性能(GDI和SlimDX)
我是一个团队的成员,该团队创建了一个工具,可以在C#/WPF中查看非常大且高度互连的图形并与之交互。查看图形和与图形交互是通过一个自定义控件完成的,该控件接收一组DrawingVisuals并将其显示在画布上。图形中的节点可能具有使用编辑器创建的自定义形状。当前控件工作得很好,并且与我们的程序相当耦合,但是当考虑更大的图(20000多个节点和大量连接)时,对性能存在合理的担忧 在做了一些研究之后,似乎有两种方法:C# 二维绘图性能(GDI和SlimDX),c#,wpf,gdi+,slimdx,C#,Wpf,Gdi+,Slimdx,我是一个团队的成员,该团队创建了一个工具,可以在C#/WPF中查看非常大且高度互连的图形并与之交互。查看图形和与图形交互是通过一个自定义控件完成的,该控件接收一组DrawingVisuals并将其显示在画布上。图形中的节点可能具有使用编辑器创建的自定义形状。当前控件工作得很好,并且与我们的程序相当耦合,但是当考虑更大的图(20000多个节点和大量连接)时,对性能存在合理的担忧 在做了一些研究之后,似乎有两种方法: 一种GDI+路由,其中图形被绘制到可写BITMAP或InteropBitmap
- 一种GDI+路由,其中图形被绘制到可写BITMAP或InteropBitmap
- SlimDX或DirectX变体(托管在D3DImage中)
鉴于这两种截然不同的方法,考虑到以下因素,哪条路线最好:
- 即使在查看整个图形时,与图形的交互也必须快速
- 更新视觉效果应快速(颜色或尺寸变化)
- 命中测试必须快速(点和矩形)
- 开发必须及时完成
看起来好像有人问了一个问题,但没有回答。让我试着列出每种方法的优缺点,这可能会让你知道该使用哪种方法 GDI专业人士
- 易于绘制矢量形状与
- 不需要包括额外的库
- 比DX慢
- 需要限制“花式”绘图(渐变等),否则可能会减慢速度
- 如果图表需要交互,可能不是一个很好的选择
- 可以在比GDI快的同时画一些漂亮的画
- 如果绘图是交互式的,这种方法会更好
- 由于绘制了基本体,因此可以在每个缩放级别控制质量
- 绘制简单形状不是很容易——你需要编写自己的抽象或使用一个库来帮助你绘制形状
- 使用GDI并不像使用GDI那么简单,尤其是在您以前没有使用过GDI的情况下
笔
、画笔
等。创建这些基本体的成本很高图形对象设置可降低质量。用户停止平移后,以高质量绘制场景
还有一件事:我没有使用SlimDX,但我尝试了Direct2D(我指的是
Microsoft.WindowsAPICodePack.DirectX.Direct2D1
)。在我的例子中,性能比GDI+快得多,但我在渲染位图时遇到了一些问题,从来没有时间找到合适的解决方案。我最近将一些绘图代码移植到DirectX,并对结果非常满意。我们主要使用位碰撞来渲染位图,并且看到可以在几分钟内测量的渲染时间减少到1-2秒左右
<>这不能直接与你的用法相比,因为我们已经使用SLIMDX从C++中的BIT攻击到C to Direct3D,但是我想你会看到性能上的好处,即使它们不是我们所看到的数量级。
我建议您考虑一下将Direct2D与SlimDX结合使用。由于某些原因,Direct2D与DirectX 11不兼容,因此需要使用DirectX 10.1。如果您在WPF中使用过绘图API,那么您将已经熟悉Direct2D,因为据我所知,它的API是基于WPF绘图API的。Direct2D的主要问题是缺少文档,而且它只能在Vista以后的版本中使用
我还没有尝试过DirectX 10/WPF互操作,但我相信这是可能的(http://stackoverflow.com/questions/1252780/d3dimage-using-dx10)
编辑:我想我会给你一个比较,从我们的代码画一个简单的多边形。首先是WPF版本:
StreamGeometry geometry = new StreamGeometry();
using (StreamGeometryContext ctx = geometry.Open())
{
foreach (Polygon polygon in mask.Polygons)
{
bool first = true;
foreach (Vector2 p in polygon.Points)
{
Point point = new Point(p.X, p.Y);
if (first)
{
ctx.BeginFigure(point, true, true);
first = false;
}
else
{
ctx.LineTo(point, false, false);
}
}
}
}
现在是Direct2D版本:
Texture2D maskTexture = helper.CreateRenderTexture(width, height);
RenderTargetProperties props = new RenderTargetProperties
{
HorizontalDpi = 96,
PixelFormat = new PixelFormat(SlimDX.DXGI.Format.Unknown, AlphaMode.Premultiplied),
Type = RenderTargetType.Default,
Usage = RenderTargetUsage.None,
VerticalDpi = 96,
};
using (SlimDX.Direct2D.Factory factory = new SlimDX.Direct2D.Factory())
using (SlimDX.DXGI.Surface surface = maskTexture.AsSurface())
using (RenderTarget target = RenderTarget.FromDXGI(factory, surface, props))
using (SlimDX.Direct2D.Brush brush = new SolidColorBrush(target, new SlimDX.Color4(System.Drawing.Color.Red)))
using (PathGeometry geometry = new PathGeometry(factory))
using (SimplifiedGeometrySink sink = geometry.Open())
{
foreach (Polygon polygon in mask.Polygons)
{
PointF[] points = new PointF[polygon.Points.Count()];
int i = 0;
foreach (Vector2 p in polygon.Points)
{
points[i++] = new PointF(p.X * width, p.Y * height);
}
sink.BeginFigure(points[0], FigureBegin.Filled);
sink.AddLines(points);
sink.EndFigure(FigureEnd.Closed);
}
sink.Close();
target.BeginDraw();
target.FillGeometry(geometry, brush);
target.EndDraw();
}
正如您所看到的,Direct2D版本的工作量稍大一些(并且依赖于我编写的一些帮助函数),但实际上非常相似。感谢您的回复!您是否有使用SlimDX(wpf集成)的经验?它能呈现的东西的数量有上限吗?我试图权衡SlimDX的学习曲线和它相对于GDI路线提供的性能优势。我相信SlimDX有一个WPF互操作性示例()。此外,虽然SlimDX/DirectX渲染的内容本身没有上限,但请记住,性能只是图形卡马力和渲染效率的函数——实际上,GDI和DirectX都是如此