コードスペランカー

ゲーム開発日誌など

WPFのお勉強 描画編その3

前回の続きで今回は幾何学的な描画について行う。
前々回でLineオブジェクトを紹介したが、Lineオブジェクトを更新する方法は、オブジェクトの数が増えると、GCの発生が大量に出るようで、1000個とか発行すると、描画処理が重くて話にならなくなる。オブジェクト数が少ないうちは良いが、多くなるにつれ加速度的に重くなるので、不安定で使いにくい。
次はCanvas.Childrenを一度全て消して書き直す方法を考えてみる。この場合、処理にかかる負荷は一定で安定はしているが、全体的に重く大量の折れ線を捌くのにむいているとはいえない。
では、大量の折れ線を捌く方法はないかというとある。StreamGeometryというクラスがありLineクラスでで1つ1つに発生するオーバーヘッドを1箇所にまとめることで負荷を非常に小さくできる。

// Pathの作成
Path MyPath = new Path();
MyPath.Stroke = Brushes.Red;
MyPath.StrokeThickness = 1;

// StreamGeometryの作成
StreamGeometry geo = new StreamGeometry();
geo.FillRule = FillRule.EvenOdd;

using (StreamGeometryContext ctx = geo.Open())
{
  // 線分の開始と終りは繋がらない
  ctx.BeginFigure(new Point(0 * (canvas1.Width / _Cycle), _buff.GetValue(0)), false, false);
  for (int i = 1; i < _Cycle -1; i++)
  {
    // 線分の中間は繋がっている
    ctx.LineTo(new Point(i * (canvas1.Width / _Cycle), _buff.GetValue(i)), true, true);
  }
  ctx.LineTo(new Point((_Cycle - 1) * (canvas1.Width / _Cycle), _buff.GetValue((_Cycle - 1))), false, false);
}
// StreamGeometryの確定
geo.Freeze();
// Pathに登録
MyPath.Data = geo;
// Pathをキャンバスに登録
canvas1.Children.Add(geo);

こんな感じで書くと、大量の角がある折れ線でも小さなコストで書くことができる。