忍者ブログ

Memeplexes

プログラミング、3DCGとその他いろいろについて

Silverlight5からXnaを使う その5 2つのDrawingSurface

DrawingSurfaceはここまで、1つだけでした。
DrawingSurfaceはXNAで3DCGを表示するコントロールです。
一つの画面に一つの3DCGが表示されるのです。

ここではそうではなく、2つの画面に3DCGを表示する準備をしてみましょう。


ここには2つのDrawingSurfaceがあります。
それぞれ背景を赤と青に塗っています。
そしてちょっとした情報を表示しています。

どうやら2つのDrawingSurfaceが使うGraphicsDeviceは共通で、スレッドも同じようです。

なお、ここでやることはViewportでも同じようなことができますが、どうやら実装レベルでは異なっているようです。


プログラム

MainPage.xaml
<UserControl x:Class="SilverlightXna06.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Grid.RowDefinitions>
            <RowDefinition Height="2*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBlock x:Name="textBlock" Grid.RowSpan="2"></TextBlock>
        <DrawingSurface Draw="DrawingSurface1_Draw"/>
        <DrawingSurface Draw="DrawingSurface2_Draw" Grid.Row="1" />
        <sdk:Label Foreground="White" Name="label1"/>
        <sdk:Label Foreground="White" Name="label2" Grid.Row="1"/>
    </Grid>
</UserControl>

MainPage.xaml.cs

using System.Windows.Controls;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Windows.Graphics;

namespace SilverlightXna06
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
            textBlock.Text = GpuError.Message;
        }

        GraphicsDevice GraphicsDevice
        {
            get { return GraphicsDeviceManager.Current.GraphicsDevice; }
        }

        private void DrawingSurface1_Draw(object sender, DrawEventArgs e)
        {
            GraphicsDevice.Clear(new Color(1f, 0, 0));
            outputLog(label1);
            e.InvalidateSurface();
        }

        private void DrawingSurface2_Draw(object sender, DrawEventArgs e)
        {
            GraphicsDevice.Clear(new Color(0, 0, 1f));
            outputLog(label2);
            e.InvalidateSurface();
        }

        private void outputLog(Label label)
        {
            var gpu = GraphicsDevice;
            var threadID = System.Threading.Thread.CurrentThread.ManagedThreadId;
            var viewport = gpu.Viewport;
            Dispatcher.BeginInvoke(delegate
            {
                label.Content = string.Format(
                    "gpu:{0}, thread:{1}, viewport.Bounds:{2}",
                    gpu.GetHashCode(),
                    threadID,
                    viewport.Bounds
                    );
            });
        }
    }
}


GpuError.cs
using System.Windows.Graphics;

namespace SilverlightXna06
{
    public class GpuError
    {
        public static bool ErrorExists
        {
            get
            {
                return GraphicsDeviceManager.Current.RenderMode != RenderMode.Hardware;
            }
        }

        public static string Message
        {
            get
            {
                if (!ErrorExists)
                { return ""; }

                string message;

                switch (GraphicsDeviceManager.Current.RenderModeReason)
                {
                    case RenderModeReason.Not3DCapable:
                        message = "あなたのグラフィックスハードウェアはこのページを表示出来ません";
                        break;
                    case RenderModeReason.GPUAccelerationDisabled:
                        message = "ハードウェアグラフィックスアクセラレーションがこのwebページでは有効にされていません。\n\n" +
                            "webサイトのオーナーに通知してください";
                        break;
                    case RenderModeReason.TemporarilyUnavailable:
                        message = "あなたのグラフィックスハードウェアは一時的に使用不可能になっています。\n\n" +
                            "webページをリロードするかブラウザを再起動してください。";
                        break;
                    case RenderModeReason.SecurityBlocked:
                        message =
                          "webサイトが3Dグラフィックスを表示できるようにするには、システム構成を変える必要があります。\n\n" +
                          "  1. ここを右クリックします。\n" +
                          "  2. [Silverlight]を選択します\n" +
                          "     ([Microsoft Silverlight の構成ダイヤログ]が表示されます)\n" +
                          "  3. [アクセス許可]タブを選択します\n" +
                          "  4. このサイトをリストの中から見つけ、その3Dグラフィックスアクセス許可を[拒否]から[許可]に変えます\n" +
                          "  5. [OK]をクリックします\n" +
                          "  6. ページをリロードします";
                        break;
                    default:
                        message = "不明なエラー";
                        break;
                }

                return "3D表示がブロックされました!\n\n\n" + message;
            }
        }
    }
}










拍手[0回]

PR