Моя задача состоит в том, чтобы нарисовать огромный график с более чем 500 000 узлов и ребра, с такими функциями, как движущиеся узлы, их выбор, удаление и т. Д. Также моя нагрузка на графический процессор составляет менее 10%, поэтому, кажется, я не использую свой графический процессор полностью. Я использую Direct2D, и я вызываю методы рисования для каждого узла и края (что, я думаю, это основная проблема!).
Мой вопрос: как я могу выполнить эту задачу с разумной производительностью?
или как я могу уменьшить вызовы рисования. Что -то вроде партийного рисунка? < /p>
Вот мой код: < /p>
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;
using SharpDX;
using SharpDX.Direct2D1;
using SharpDX.Windows;
namespace SharpD2D
{
public partial class Form1 : Form
{
List lstGeoms;
public Factory Factory2D { get; private set; }
public SharpDX.DirectWrite.Factory FactoryDWrite { get; private set; }
public RenderTarget RenderTarget2D { get; private set; }
public RenderControl renderControl { get; private set; }
public Form1()
{
InitializeComponent();
InitRendererControl(this.Size);
InitDirect2DAndDirectWrite();
lstGeoms = Generator.GeomGenerator.getGeoms(Factory2D);
}
private void InitRendererControl(System.Drawing.Size? renderSize = null)
{
// create instance
renderControl = new RenderControl();
// renderControl.BackColor = System.Drawing.Color.Transparent;
if (renderSize.HasValue)
renderControl.Size = renderControl.ClientSize = renderSize.Value;
//events
renderControl.Paint += renderControl_Paint;
this.Controls.Add(renderControl);
}
private void renderControl_Paint(object sender, PaintEventArgs e)
{
renderBoard();
}
private void InitDirect2DAndDirectWrite()
{
Factory2D = new SharpDX.Direct2D1.Factory(FactoryType.MultiThreaded);
FactoryDWrite = new SharpDX.DirectWrite.Factory(SharpDX.DirectWrite.FactoryType.Shared);
var properties = new HwndRenderTargetProperties();
properties.Hwnd = renderControl.Handle;
properties.PixelSize = new Size2(renderControl.ClientSize.Width, renderControl.ClientSize.Height);
properties.PresentOptions = PresentOptions.RetainContents;
RenderTarget2D = new WindowRenderTarget(Factory2D, new RenderTargetProperties(new SharpDX.Direct2D1.PixelFormat(SharpDX.DXGI.Format.Unknown, AlphaMode.Premultiplied)), properties);
RenderTarget2D.AntialiasMode = AntialiasMode.Aliased;
RenderTarget2D.TextAntialiasMode = TextAntialiasMode.Aliased;
}
private void renderBoard()
{
RenderTarget2D.AntialiasMode = AntialiasMode.Aliased;
Stopwatch sw = new Stopwatch();
var brush = new SharpDX.Direct2D1.SolidColorBrush(RenderTarget2D, new Color4(0.3f, 0.5f, 0.9f, 1f));
RenderLoop.Run(renderControl, () =>
{
sw.Restart();
RenderTarget2D.BeginDraw();
RenderTarget2D.Clear(new Color4(0f, 0f, 0f, 1f));
foreach (var item in lstGeoms)
{
RenderTarget2D.FillGeometry(item, brush);
}
RenderTarget2D.Flush();
RenderTarget2D.EndDraw();
sw.Stop();
var totalElappsed = sw.ElapsedMilliseconds;
var fps = 1000 / (totalElappsed == 0 ? 0.000001 : totalElappsed);
Console.WriteLine($"Count: {lstGeoms.Count} : {totalElappsed.ToString()} , {fps}");
});
}
}
}
< /code>
и класс Geomgenerator, который генерирует 500K случайных эллипсов: < /p>
using SharpDX;
using SharpDX.Direct2D1;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Generator
{
public class GeomGenerator
{
[StructLayout(LayoutKind.Sequential)]
public struct Vertex
{
public Vector4 Position;
public SharpDX.ColorBGRA Color;
}
public static List getGeoms(SharpDX.Direct2D1.Factory d2dFactory)
{
var lstGeoms = new List();
int count = 500 * 1000;
Random r = new Random();
var bound = 650;
var lowerBound = 0;
var upperBound = bound;
for (int i = 0; i < count; i++)
{
var location = new Point(r.Next(lowerBound, upperBound), r.Next(lowerBound, upperBound));
var center = new SharpDX.Mathematics.Interop.RawVector2() { X = location.X, Y = location.Y };
var ellipse = new SharpDX.Direct2D1.Ellipse(center, 1, 1);
var mainGeo = new EllipseGeometry(d2dFactory, ellipse);
lstGeoms.Add(mainGeo);
}
return lstGeoms;
}
}
}
Моя задача состоит в том, чтобы нарисовать огромный график с более чем 500 000 узлов и ребра, с такими функциями, как движущиеся узлы, их выбор, удаление и т. Д. Также моя нагрузка на графический процессор составляет менее 10%, поэтому, кажется, я не использую свой графический процессор полностью. Я использую Direct2D, и я вызываю методы рисования для каждого узла и края (что, я думаю, это основная проблема!).
Мой вопрос: как я могу выполнить эту задачу с разумной производительностью? или как я могу уменьшить вызовы рисования. Что -то вроде партийного рисунка? < /p> Вот мой код: < /p> [code]using System; using System.Collections.Generic; using System.Diagnostics; using System.Windows.Forms; using SharpDX; using SharpDX.Direct2D1; using SharpDX.Windows; namespace SharpD2D { public partial class Form1 : Form { List lstGeoms; public Factory Factory2D { get; private set; } public SharpDX.DirectWrite.Factory FactoryDWrite { get; private set; } public RenderTarget RenderTarget2D { get; private set; } public RenderControl renderControl { get; private set; } public Form1() { InitializeComponent(); InitRendererControl(this.Size); InitDirect2DAndDirectWrite(); lstGeoms = Generator.GeomGenerator.getGeoms(Factory2D); }
}); } } } < /code> и класс Geomgenerator, который генерирует 500K случайных эллипсов: < /p> using SharpDX; using SharpDX.Direct2D1; using System; using System.Collections.Generic; using System.Runtime.InteropServices;
namespace Generator { public class GeomGenerator { [StructLayout(LayoutKind.Sequential)] public struct Vertex { public Vector4 Position; public SharpDX.ColorBGRA Color; } public static List getGeoms(SharpDX.Direct2D1.Factory d2dFactory) { var lstGeoms = new List(); int count = 500 * 1000; Random r = new Random(); var bound = 650; var lowerBound = 0; var upperBound = bound;
for (int i = 0; i < count; i++) { var location = new Point(r.Next(lowerBound, upperBound), r.Next(lowerBound, upperBound)); var center = new SharpDX.Mathematics.Interop.RawVector2() { X = location.X, Y = location.Y }; var ellipse = new SharpDX.Direct2D1.Ellipse(center, 1, 1); var mainGeo = new EllipseGeometry(d2dFactory, ellipse); lstGeoms.Add(mainGeo);