我是一个团队的一员,该团队创建了一个工具,用于查看C#/ WPF中非常大且互连的图形并与之交互。查看图形并与图形交互是通过一个自定义控件完成的,该控件接受一组DrawingVisual并在画布上显示它们。图中的节点可能具有使用我们的编辑器创建的自定义形状。当前控件运行良好,并且与我们的程序相当,但在考虑更大的图形(20,000多个节点和大量连接)时,存在对性能的合理担忧。
经过一些研究后,似乎有两种方法:
鉴于这两种极为不同的方法,哪种方法最适合考虑:
您会使用哪种方法?为什么?
编辑:
看起来similar question被问到但没有回答。
答案 0 :(得分:7)
我为我的cartographic application使用GDI。虽然GDI +比DirectX慢,但我发现有很多东西和技巧可以用来加快速度。在绘制数据之前,大量的CPU用于准备数据,因此GDI不应该是那里唯一的瓶颈。
需要注意的事项(这些也足以应用于其他图形引擎):
Pen
,Brush
等。创建这些原语非常昂贵。Graphics
对象设置会降低质量。用户停止平移后,以高质量绘制场景。另一件事:我没有使用过SlimDX,但我确实尝试过Direct2D(我指的是Microsoft.WindowsAPICodePack.DirectX.Direct2D1
)。在我的情况下,性能比GDI +快得多,但我在渲染位图时遇到了一些问题,而且没有时间找到合适的解决方案。
答案 1 :(得分:3)
我最近将一些绘图代码移植到DirectX,并对结果非常满意。我们主要使用bit-bashing渲染位图,并且看到渲染时间可以在几分钟内测量,减少到大约1-2秒。
这不能直接与你的使用进行比较,因为我们已经使用SlimDX从C ++中的bit-bashing转变为C#中的Direct3D,但我想你会看到性能优势,即使它们不是我们正在看到的程度。
我建议你看一下使用Direct2D和SlimDX。您将需要使用DirectX 10.1,因为Direct2D由于某种原因与DirectX 11不兼容。如果您在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版本的工作量略多(并且依赖于我编写的一些辅助函数),但实际上它非常相似。
答案 2 :(得分:1)
让我尝试列出每种方法的优点和缺点 - 这可能会让您对使用哪种方法有所了解。
GDI专业人士
GDI缺点
SlimDX专业人士
SlimDX缺点
也许更多我忘了放在这里,但也许这些会对初学者有用吗?
-A。