開発環境 |
Microsoft Visual Studio Express 2013 for Windows Desktop |
実行環境 |
Microsoft Windows 8.1 (64bit) |
プロジェクトの種類 |
Visual C#/WPF アプリケーション |
プロジェクト名 |
WpfMandelbrot |
参考
以下のファイルをプロジェクトに追加する。
Mandelbrot.cs |
クラス |
|
Mandelbrot.fx |
既存の項目 |
ビルド アクション:なし |
Mandelbrot.ps |
既存の項目 |
ビルド アクション:Resource |
MainWindow.xaml
<Window x:Class="WpfMandelbrot.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfMandelbrot"
Title="MainWindow" Height="500" Width="500">
<Grid Background="LightBlue">
<Grid.Effect>
<local:Mandelbrot x:Name="Mandelbrot" />
</Grid.Effect>
</Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Media3D;
using System.Windows.Threading;
namespace WpfMandelbrot
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
private DispatcherTimer intervalTimer = new DispatcherTimer();
private Point3D pos = new Point3D(0, 0, 1);
public MainWindow()
{
InitializeComponent();
intervalTimer.Interval = TimeSpan.FromMilliseconds(30);
intervalTimer.Tick += intervalTimer_Tick;
intervalTimer.Start();
}
private void intervalTimer_Tick(object sender, EventArgs e)
{
if (Keyboard.IsKeyDown(Key.Escape)) Application.Current.Shutdown();
if (Keyboard.IsKeyDown(Key.Up)) pos.Y -= pos.Z * 0.01;
if (Keyboard.IsKeyDown(Key.Down)) pos.Y += pos.Z * 0.01;
if (Keyboard.IsKeyDown(Key.Left)) pos.X -= pos.Z * 0.01;
if (Keyboard.IsKeyDown(Key.Right)) pos.X += pos.Z * 0.01;
if (Keyboard.IsKeyDown(Key.PageUp)) pos.Z *= 0.99;
if (Keyboard.IsKeyDown(Key.PageDown)) pos.Z *= 1.01;
Mandelbrot.Center = pos;
Mandelbrot.Aspect = ActualHeight / ActualWidth;
Title = string.Format("WpfMandelbrot ({0:f6},{1:f6}) {2:f6}", pos.X, pos.Y, pos.Z);
}
}
}
Mandelbrot.cs
using System;
using System.Reflection;
using System.Windows;
using System.Windows.Media.Effects;
using System.Windows.Media.Media3D;
namespace WpfMandelbrot
{
public class Mandelbrot : ShaderEffect
{
private static PixelShader _pixelShader =
new PixelShader() { UriSource = new Uri(@"Mandelbrot.ps", UriKind.RelativeOrAbsolute) };
public Mandelbrot()
{
PixelShader = _pixelShader;
UpdateShaderValue(CenterProperty);
UpdateShaderValue(AspectProperty);
}
//----------------------------------------------------------------------
public Point3D Center
{
get { return (Point3D)GetValue(CenterProperty); }
set { SetValue(CenterProperty, value); }
}
public static readonly DependencyProperty CenterProperty =
DependencyProperty.Register("Center", typeof(Point3D), typeof(Mandelbrot),
new UIPropertyMetadata(new Point3D(0, 0, 1), PixelShaderConstantCallback(0)));
//----------------------------------------------------------------------
public double Aspect
{
get { return (double)GetValue(AspectProperty); }
set { SetValue(AspectProperty, value); }
}
public static readonly DependencyProperty AspectProperty =
DependencyProperty.Register("Aspect", typeof(double), typeof(Mandelbrot),
new UIPropertyMetadata(1.0, PixelShaderConstantCallback(1)));
}
}
Mandelbrot.fx
float4 center : register(c0);
float aspect : register(c1);
float4 main(float2 uv : TEXCOORD) : COLOR
{
const int MaxIterate = 254;
const float2 c = (uv - 0.5) * float2(1.0, aspect) * center.z + center.xy;
float2 p = 0;
int n;
for (n = 0; n < MaxIterate && dot(p, p) < 4.0; n++) {
p = float2(p.x * p.x - p.y * p.y, 2.0 * p.x * p.y) + c;
}
float4 color;
if (n < MaxIterate) {
float u = (float)n / (float)MaxIterate;
color.rgb = float3(u, u, 1.0 - u);
}
else {
color.rgb = 0.0;
}
color.a = 1.0;
return color;
}
プロジェクトのプロパティ
ビルド イベント/ビルド前に実行するコマンド ライン
"C:\Program Files (x86)\Windows Kits\8.1\bin\x86\fxc.exe"^
/T ps_3_0 /Fo $(ProjectDir)Mandelbrot.ps $(ProjectDir)Mandelbrot.fx
最終更新:2014年06月01日 20:49