【发布时间】:2015-02-16 08:26:02
【问题描述】:
使用 Direct2D (Sharpdx) 绘制复杂绘图的方法如何?
实际上我使用的是 WindowsRenderTarget,将它与 Direct2D1.Factory 连接并绘制到 RenderControl。
Factory2D = new SharpDX.Direct2D1.Factory(FactoryType.MultiThreaded);
FactoryWrite = new SharpDX.DirectWrite.Factory();
var properties = new HwndRenderTargetProperties();
properties.Hwnd = this.Handle;
properties.PixelSize = new Size2(this.ClientSize.Width, this.ClientSize.Height);
properties.PresentOptions = PresentOptions.RetainContents;
RenderTarget2D = new WindowRenderTarget(Factory2D, new RenderTargetProperties(new PixelFormat(Format.Unknown, AlphaMode.Premultiplied)), properties);
RenderTarget2D.AntialiasMode = AntialiasMode.PerPrimitive;
绘图是在窗体的 Paint Event 中完成的:
RenderTarget2D.BeginDraw();
RenderTarget2D.Clear(Color4.Black);
drawProgress(); // Doing Paintings like DrawLine, Multiple PathGeometrys, DrawEllipse and DrawText
RenderTarget2d.EndDraw();
在 MouseMove/MouseWheel 事件中,将重新计算绘图(用于缩放或计算将要显示的元素)。这个过程大约需要8-10ms。 下一步其实是
this.Refresh();
这里,我猜,是问题所在,这个进度需要长达 140ms。
所以情节的缩放/移动大约有 7fps。
另外程序在刷新控件时占用的内存越来越大
////编辑
线条画法:
private void drawLines(Pen pen, PointF[] drawElements)
{
SolidColorBrush tempBrush = new SolidColorBrush(RenderTarget2D, SharpDX.Color.FromRgba(pen.Color.ToArgb()));
int countDrawing = (drawElements.Length / 2) + drawElements.Length % 2;
for (int i = 0; i < countDrawing; i++)
{
drawLine(new Vector2(drawElements[i].X, drawElements[i].Y), new Vector2(drawElements[i + 1].X, drawElements[i + 1].Y), brushWhite);
}
}
绘制几何图形:
RenderTarget2D.DrawGeometry(graphicPathToPathGeometry(p), penToSolidColorBrush(pen));
private PathGeometry graphicPathToPathGeometry(GraphicsPath path)
{
geometry = new PathGeometry(Factory2D);
sink = geometry.Open();
if (path.PointCount > 0)
{
sink.BeginFigure(new Vector2(path.PathPoints[path.PointCount - 1].X, path.PathPoints[path.PointCount - 1].Y), FigureBegin.Hollow);
sink.AddLines(pointFToVector2(path.PathPoints));
sink.EndFigure(new FigureEnd());
sink.Close();
}
return geometry;
}
在鼠标移动中,仅通过建立 Cursor.Position.X/Y old 和 Cursor.Position.X/Y new 之间的差异来重新计算绘图。所以这些线会经常重新计算:)
【问题讨论】:
-
据我了解,您在 MouseMove/MouseWheel 结束时调用
this.Refresh(),对吗?您如何准确地衡量性能?当您从第一个 sn-p 初始化资源时?您的第二个 sn-p 是 Paint 事件的全部内容吗?您是否在drawProgress()中创建任何资源? -
我用秒表测量它,该秒表将在刷新事件中重置。实际上我开始使用渲染循环并在那里做油漆。我想问题是绘图过程。我实际上每次都重新绘制完整的画,即使屏幕是空白的。我认为我的方法是错误的。另一件事是内存使用情况。程序越来越大。我从不处理任何东西,但也不知道该怎么做。渲染目标被渲染循环阻塞
-
没有看到你的绘图过程(即-
drawProgress()),我们只会猜测。 -
绘制进度有大量计算 :) 大约 500 条绘制线,300 条路径几何(没有复杂的,但这是最大的性能不足),100 条椭圆。但这不是问题。问题是我每帧都重新绘制这些东西。我使用了 MiniRect 示例作为基础。也没有重置 RenderTarget 来清除内存。我认为我使用了错误的基础知识,我从不使用 SwapChain 或 Backbuffer。我从来没有设置视口或类似的东西。当我的程序运行 30 秒时,它达到 1,6gigs ram:/
-
我只能猜测...您可能正在
drawProgress()中创建资源。你不应该。一个核心原则是您必须立即创建资源,然后在您的绘图例程中重用它们。 “重置 RenderTarget”是什么意思?另外,您有独立的视频适配器还是使用 cpu 集成的适配器?
标签: c# performance direct2d sharpdx