Windows ストア アプリで C++/CX を使ってゲームを使えば、グラフィックボードの性能を最大限に引き出せることが分かっているのですが、では、XAML でのアニメーション(主に storyboard)の場合は、どのくらいグラフィックボードの GPU を使っているか?ってのを調べてみます。
目的としては「小難しい C++/CX とか DirectX を使わなくても、XAML のアニメーション効果を使えばそこそこゲームが作れるのでは?」ってところです。実際、C++/CX は高度な3D効果の使い、単純なテキスト表示などは XAML で表示させる、という手法が Microsoft より紹介されているわけで、そのあたりは、そのあたりで。
■ベンチマークアプリを作る
単純に5000個の円(Ellipse)を表示させて、storyboard で動かしています。storybaord クラスのコピーには、以前作った Storyboard.Clone を少し修正して使っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | List<Storyboard> sbs; /// <summary> /// 円を作成 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void CreateClick( object sender, RoutedEventArgs e) { var rnd = new Random(); // 100個のEllipseを適当に並べる var xml = @" <Ellipse xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" Fill=""#FFF4F4F5"" HorizontalAlignment=""Left"" Height=""50"" Margin=""94,137,0,0"" Grid.Row=""1"" Stroke=""Black"" VerticalAlignment=""Top"" Width=""50"" RenderTransformOrigin=""0.5,0.5""> <Ellipse.RenderTransform> <CompositeTransform/> </Ellipse.RenderTransform> </Ellipse> " ; sbs = new List<Storyboard>(); for ( int i = 0; i < 5000; i++) { object obj = XamlReader.Load(xml); Ellipse el = obj as Ellipse; Canvas.SetLeft(el, 0); Canvas.SetTop(el, 0); canvas.Children.Add(el); var sb = sbMove.Clone(); sb.SetTarget(el); sb.AutoReverse = true ; sb.RepeatBehavior = RepeatBehavior.Forever; int x1 = rnd.Next(800); int y1 = rnd.Next(800); int x2 = rnd.Next(800); int y2 = rnd.Next(800); ((DoubleAnimation)sb.Children[0]).From = x1; ((DoubleAnimation)sb.Children[1]).From = y1; ((DoubleAnimation)sb.Children[0]).To = x2; ((DoubleAnimation)sb.Children[1]).To = y2; TimeSpan ts = new TimeSpan(0, 0, rnd.Next(5) + 1); ((DoubleAnimation)sb.Children[0]).Duration = ts; ((DoubleAnimation)sb.Children[1]).Duration = ts; ((ColorAnimation)sb.Children[2]).Duration = ts; switch (rnd.Next(3)) { case 0: ((ColorAnimation)sb.Children[2]).To = Windows.UI.Colors.Red; break ; case 1: ((ColorAnimation)sb.Children[2]).To = Windows.UI.Colors.Yellow; break ; case 2: ((ColorAnimation)sb.Children[2]).To = Windows.UI.Colors.Blue; break ; } sbs.Add(sb); } } private void StartClick( object sender, RoutedEventArgs e) { // アニメーション開始 foreach ( var sb in sbs) { sb.Begin(); } } private void StopClick( object sender, RoutedEventArgs e) { // アニメーション停止 foreach ( var sb in sbs) { sb.Stop(); } this .sbMove.Stop(); } |
動かすとこんな感じになります。円が5000個(半分ほど見えていませんが)うにょうにょと動きます。
■CPU と GPU の負荷を見てみる。
Process Explorer で XamlBenchMark の負荷をみていくと、GPU を 25% ほど使った状態になります。この PC だとそれほど重くないのですが、うまく動かない場合は、1000 個位に減らして動かしてみてください。
この時の CPU 負荷は、26% 程度です。GPU を使わない場合(グラフィックボードを積まない場合)がどうなるのかは、別の PC で検証したいと思います。
プログラムを修正して、ぱらぱらアニメを1000個位動かしてみたいですね。体感速度がそれほど落ちるものでなければ、それなりのアクションパズルゲームとかが C#+XAML+storyboard の組み合わせでできるのではないか、と考えています。
■サンプルのダウンロード
ベンチマークのダウンロードは以下からできます XamlBenchMark.zip
ちなみに、5000個の円を surface RT で実行させると作成時にがっつりと止まってしまうので、1000程度に変更したほうが無難。後でサンプルも変えておきます。