Direct2D绘图方法/性能

时间:2015-02-16 08:26:02

标签: c# performance direct2d sharpdx

如何使用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;

绘图在表格的油漆事件中完成:

RenderTarget2D.BeginDraw();
RenderTarget2D.Clear(Color4.Black);
drawProgress(); // Doing Paintings like DrawLine, Multiple PathGeometrys, DrawEllipse and DrawText
RenderTarget2d.EndDraw();

在MouseMove / MouseWheel事件中,将重新计算绘图(用于缩放或计算将要显示的元素)。这个过程大约需要8-10ms。 下一步实际上是

this.Refresh(); 

在这里,我猜是问题,这个进展需要140毫秒。

因此,绘图的缩放/移动大约为7fps。

刷新Control

时,程序也会占用越来越多的内存

////修改

画线:

    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之间的差异来重新计算绘图。因此,这些行将经常重新计算:)

2 个答案:

答案 0 :(得分:1)

主要瓶颈是您的graphicPathToPathGeometry()功能。你正在创造和&#34;填充&#34;渲染循环中的PathGeometry。如上所述,核心原则是您必须立即创建资源,然后在绘图例程中重复使用它们。

关于您的内存泄漏...您的代码示例没有提供足够的信息,但很可能您没有释放您正在创建的资源(即PathGeometrySolidColorBrush和我们不看的东西)。

最简单的建议是 - 使用渲染循环仅用于渲染/绘制和重用资源,而不是重新创建它们。

Improving the performance of Direct2D apps

答案 1 :(得分:0)

问题的一部分是:

SolidColorBrush tempBrush = new SolidColorBrush(RenderTarget2D, SharpDX.Color.FromRgba(pen.Color.ToArgb()));

在renderloop中创建任何类型的对象会在应用程序中造成大量内存缺失。绘制现有价值是可行的方法。

我想性能问题也将基于这个问题。