任意3D文字が回転するスクリーンセーバー

WPFでTextから2DのPathに変換しました。じゃあ3Dは?というのが浮かんだ内容ですが、これが結構難しい。行きついた情報はこちら、あのProgramming Windowsで有名なCharles Petzold氏のMSDNマガジンへの寄稿でした。

詳細は追って理解するとしてこれを使ったスクリーンセーバを作ってみます。WPFによるスクリーンセーバーの作り方はこちら、非常に分かりやすく解説されています。

 

App.xaml.cs

namespace WpfText3DScreenSaver
{
    using System.Globalization;
    using System.Windows;

    public partial class App : Application
    {
        private MainWindow window = new MainWindow();

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            if (e.Args.Length > 0){
                string mode = e.Args[0].ToLower(CultureInfo.InvariantCulture);
                if (mode.StartsWith("/c")){
                    ShowConfig();
                    return;
                }
                else if (mode.StartsWith("/p"))
                {
                    return;
                }
            }
            SaveScreen();
        }

        private void ShowConfig()
        {
            var settingWindow = new TextSettingWindow();
            settingWindow.ShowDialog();
        }
        private void SaveScreen()
        {
            window.Topmost = true;
            window.Left = 0;
            window.Top = 0;
            window.WindowState = WindowState.Maximized;
            window.Show();
        }
    }
}

App.xaml

<Application x:Class="WpfText3DScreenSaver.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Startup="Application_Startup">
    <Application.Resources>
    </Application.Resources>
</Application>

StartupUriでなく、Startupになっているのに注意。Startupとしてはcsで定義したハンドラを指定しています。設定ウィンドウはこんな感じ。

 TextSettingWindow.xaml.cs

namespace WpfText3DScreenSaver
{
    using System.Windows;

    public partial class TextSettingWindow : Window
    {
        public TextSettingWindow()
        {
            InitializeComponent();
            textbox.Text = Properties.Settings.Default.Text3D;
            setbutton.Click += (_, __) =>{
                DialogResult = true;
                Properties.Settings.Default.Text3D = textbox.Text;
                Properties.Settings.Default.Save();
                Close();
            };
            cancelbutton.Click += (_, __) =>
            {
                DialogResult = false;
                Close();
            };
        }
    }
}

TextSettingWindow.xaml

<Window x:Class="WpfText3DScreenSaver.TextSettingWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="TextSettingWindow" Height="104" Width="300">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="140"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="2*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <TextBox Name="textbox" Grid.ColumnSpan="3" TextWrapping="Wrap" Text="TextBox"/>
        <Button Name="setbutton"  Content="設定" Grid.Column="1" Grid.Row="1"/>
        <Button Name="cancelbutton" Content="キャンセル" Grid.Column="2" Grid.Row="1"/>
    </Grid>
</Window>

settingwindow

ポイントって言うほどではないんですが、設定時と実行時ではプログラム引数違いなだけでそれぞれ終了してしまうため、設定を保持しておく必要があります。ここではフツーにSettingsを使って設定を保持しておくことにします。

 

さて、メインとなるウィンドウはこちら。

 MainWindow.xaml

<Window x:Class="WpfText3DScreenSaver.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:petzold="clr-namespace:Petzold.Text3D;assembly=Petzold.Text3D"
        Title="MainWindow" Height="350" Width="525" WindowStyle="None">
    <Grid>
        <Viewport3D>
            <petzold:SolidText x:Name="field"
                       Text="任意文字"
                       FontFamily="Times New Roman"
                       FontWeight="Bold"
                       Origin="-1.5 0.5" Depth="0.5">
                <petzold:SolidText.Material>
                    <MaterialGroup>
                        <DiffuseMaterial Brush="Blue" />
                        <SpecularMaterial Brush="White" />
                    </MaterialGroup>
                </petzold:SolidText.Material>

                <petzold:SolidText.BackMaterial>
                    <MaterialGroup>
                        <DiffuseMaterial Brush="Red" />
                        <SpecularMaterial Brush="White" />
                    </MaterialGroup>
                </petzold:SolidText.BackMaterial>

                <petzold:SolidText.SideMaterial>
                    <MaterialGroup>
                        <DiffuseMaterial>
                            <DiffuseMaterial.Brush>
                                <LinearGradientBrush StartPoint="0 0"
                                                 EndPoint="0 1">
                                    <GradientStop Offset="0" Color="Blue" />
                                    <GradientStop Offset="1" Color="Red" />
                                </LinearGradientBrush>
                            </DiffuseMaterial.Brush>
                        </DiffuseMaterial>
                        <SpecularMaterial Brush="White" />
                    </MaterialGroup>
                </petzold:SolidText.SideMaterial>

                 <!--Transform.-->
                <petzold:SolidText.Transform>
                    <RotateTransform3D>
                        <RotateTransform3D.Rotation>
                            <AxisAngleRotation3D x:Name="rotate" Axis="1 1 0" />
                        </RotateTransform3D.Rotation>
                    </RotateTransform3D>
                </petzold:SolidText.Transform>
            </petzold:SolidText>

             <!--Lights.-->
            <ModelVisual3D>
                <ModelVisual3D.Content>
                    <Model3DGroup>
                        <AmbientLight Color="#404040" />
                        <DirectionalLight Color="#C0C0C0" Direction="2 -3 -1" />
                    </Model3DGroup>
                </ModelVisual3D.Content>
            </ModelVisual3D>

             <!--Camera.-->
            <Viewport3D.Camera>
                <PerspectiveCamera Position="0 0 8" UpDirection="0 1 0"
                               LookDirection="0 0 -1" FieldOfView="45" />
            </Viewport3D.Camera>
        </Viewport3D>

         <!--Animation.-->
        <Grid.Triggers>
            <EventTrigger RoutedEvent="Page.Loaded">
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="rotate"
                                     Storyboard.TargetProperty="Angle"
                                     From="0" To="360" Duration="0:0:15"
                                     RepeatBehavior="Forever" />
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Grid.Triggers>
    </Grid>
</Window>

MainWindow.xaml.cs

namespace WpfText3DScreenSaver
{
    using System.Windows;

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            field.Text = Properties.Settings.Default.Text3D;
            this.MouseMove += (_, __) => Close();
        }
    }
}

3D表示は全体的にPetzold.Text3D DLLに依存しています。MSDNからソースコードも落とせるので落として見ると良いかと。これをexeとしてビルドした後、srcに拡張しを変更して、ファイルを右クリック→インストールを実行した様子はこちら。

setting

これを実行した画面キャプチャした様子はこちら。

scrsave

Text→3Dへの変換は追って理解していくことにします。

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中