D3DImage チュートリアル ⑦ UIと制御の追加

Published 27 April 09 03:52 PM | hiroyuk 

D3DImageの上に半透明のメニューペインを追加し、自動回転の開始・停止用とワイヤーフレーム表示用のチェックボックスを2つ追加します。

D3DRenderer.h

まず、レンダリング時に自動回転とワイヤーフレームのフラグを渡せるようにします。

VOID Render(bool b_AutoRotation, bool b_WireframeMode);

D3DRenderer.cpp

それを基にレンダーステートを変更するようD3DRenderer.cppを編集します。

VOID Render(bool b_AutoRotation, bool b_WireframeMode)
{
  // Clear the backbuffer and the zbuffer
  g_pd3dDevice->Clear( 0, NULL, 
    D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
   
D3DCOLOR_ARGB( 0, 0, 0, 0 ), 1.0f, 0 );

 

    // Begin the scene
  if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
  {
    // Setup the world, view, and projection matrices
    // SetupMatrices();
    if (b_AutoRotation) SetupMatrices();
    g_pd3dDevice->SetRenderState(D3DRS_FILLMODE,
      (b_WireframeMode) ? D3DFILL_WIREFRAME : D3DFILL_SOLID);
    g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,
      (b_WireframeMode) ? D3DCULL_NONE : D3DCULL_CCW);

これだけでもよいのですが、もともとの回転が時間を基にしているため、一度回転を止めてから再開すると、ジャンプしてしまうので、SetupMatrices()も少し変更します。

VOID SetupMatrices()
{
 
// Set up world matrix
  D3DXMATRIX matWorld;
 
// D3DXMatrixRotationY( &matWorld,
      timeGetTime() / 1000.0f );
  static float angle = 0.0f;
  D3DXMatrixRotationY( &matWorld, angle+=0.03f );

D3DWrapper.cpp

ラッパーでは、前述のフラグをパブリック プロパティとして定義し、::Renderメソッド呼び出しの引数とします。

public ref class D3DWrapper 

  private:
   bool _rotation;
   bool _wireframe;

 

  public
   D3DWrapper()
   {
    _rotation = true;
    _wireframe = false;
   }
   property bool AutoRotate
   {
    bool get() {return _rotation;}
    void set(bool value) { _rotation = value;}
   }
   property bool RenderWireframe
   {
    bool get() {return _wireframe;}
    void set(bool value) { _wireframe = value;}
   }

...

    VOID Render(int% width, int% height) 
   
      ::Render(_rotation, _wireframe); 
      width = SCREEN_WIDTH; 
      height = SCREEN_HEIGHT; 
    }

Window1.xaml

XAMLでは、メニューを追加します。

<StackPanel HorizontalAlignment="Left" Width="100" Margin="5">
  <StackPanel.Background>
    <SolidColorBrush Color="Black" Opacity="0.3"/>
  </StackPanel.Background>
  <CheckBox Name="Rot" Margin="5" Content="Rotation"
 
  Foreground="White" Unchecked="RotationChanged"
    Checked
="RotationChanged" IsChecked="True" />
  <CheckBox Name="Wire" Margin="5" Content="Wireframe"
    Foreground
="White" Unchecked="WireframeChanged"
    Checked
="WireframeChanged" IsChecked="False" />
</StackPanel>

Window1.xaml.cs

コードビハインドのC#ではコールバックを実装し、前述のフラグをセットします。

private void RotationChanged(object sender, RoutedEventArgs e)
{
 
CheckBox c = sender as CheckBox;
 
myD3DScene.AutoRotate = c.IsChecked.Value;
}

private void WireframeChanged(object sender, RoutedEventArgs)
{
  CheckBox c = sender as CheckBox;
  myD3DScene.RenderWireframe = c.IsChecked.Value;
}

F5キーを押してデバッグ実行してください。以下のようにメニュー付きでトラが回転します。Rotationをオフにすると回転が止まります。Wireframeをオンにするとワイヤーフレームのトラになります。

image

これら以外にも、マウスでの座標変換などのいろいろな制御も可能でしょう。WPFなので、コントロールテンプレートを変更してもっとかっこいいメニューにすることもできるでしょう。使いやすいUIをWPFで、高速な3DをDirect3Dでという組み合わせは、なかなか便利だと思います。

完成したプロジェクトは「第0回はじめに」にあります。

Comments

No Comments
Anonymous comments are disabled

About hiroyuk

マイクロソフト㈱エバンジェリスト。北海道大学理学部物理学科卒。リアルタイム3Dグラフィックスを専門とし、グラフィックスやシェーダに関する技術文章を執筆・講演。 DirectX SDK日本語ドキュメントの開発に携わるとともに、Windows Presentation Foundation プログラミング(オーム社)、Game Programming Gemsシリーズ、リアルタイム レンダリング第2版(ボーンデジタル)、Texturing & Modeling, A Procedural Approach などを翻訳・監修、XAMLプログラミング(ソフトバンク クリエイティブ)を執筆。趣味は薪割り。

Search

This Blog

DirectX 情報

Silverlight 情報

Windows 情報

WPF 情報

並列コンピューティング情報

著書

Syndication

Page view tracker