本サイトでは、アフィリエイト広告およびGoogleアドセンスを利用しています。

ドッキングウィンドウ on WPF での OpenGLView

前回の延長戦で、ドッキングウィンドウとの組み合わせを試してみました。
ドッキングウィンドウには AvalonDock (WPF Extended Toolkit 付属) を用いています。

はじめに

AvalonDock でドッキング可能なドキュメントとして、前回の カスタム版 D3D11Image を貼り付けています。
ここに OpenGL の描画をはめ込む形です。

今までのものと大きく異なるのは以下の点だと思います。

  • 独立したウィンドウになることがある(フローティングウィンドウ)
  • 表示/非表示のタイミング
  • Window に貼り付けられているわけでなく UserControl 以下

これらの条件変化によって、動きが変わるかを確認してみました。

wpf_avalondock_ogl

実験結果

UserControl 以下になるため、ウィンドウハンドルの取得の方法について再検討が必要でした。

今までのコードでは WindowsInteropHelper から簡単にウィンドウハンドルが得られましたが、それを変更することが必要でした。
独立したウィンドウとなることも考慮して、親ウィンドウがいればそちらを、なければ自身のハンドルを使うようにして対処しています。
それぞれのハンドルの取り方は以下のようになります。GetParent は Win32API です。

HwndSource wpfHandle = PresentationSource.FromVisual(this) as HwndSource;
IntPtr hwndParent = GetParent(wpfHandle.Handle);

これにより初期化して動くまでは到達しました。
表示・非表示のタイミングについては AvalonDock の関係だとは思うのですが、表示されたときにコントロールの初期化、非表示になったときに解放処理が行われました。
従来型の実装のままでは、タブを操作して表示・非表示を変更されるたびにこれらが呼び出されてしまいました。
このコントロールを実用にする前にはちょっと対策しなくてはいけないと思っているポイントです。

wpf_avalondock_d3dimage_ogl

上記の実行例では、回転のパラメータが static 変数なのでスムーズに動いているように見えますが、毎回初期化走ってます。

WinFormsHost を使う

領空問題 (Airspace) のため、使いたくなかったと前回記述しましたが、気になったのでこちらの方でも実験してみました。
C# の WinForms での実装で OpenGL の何かが無いかなと探した結果、 SharpGL というものを見つけました。
他にも TAO Framework だとか OpenTK とかありますが、ライブラリとしての大きさの点から SharpGL を選択しました。

また今回 WinForms のテストのため SharpGL の WPF 版は未使用です。

早速コントロールを貼り付けようとして手間取りました。
WinFormsHost を使う場合には参照に WindowsFormsIntegration, System.Windows.Forms が必要となります。
また SharpGL も SharpGL だけでなく SharpGL.WinForms も参照に追加が必要でした。

若干の手間取りはありましたが、以下のように xaml を記述しました。


  
    
  

いくつかのコードについてコードビハインドでの記述が必要になるようです。
ここでは適当に描画の部分で teapot を描画するようにしてみました。
このウィンドウとドッキングウィンドウの仕組みに入れてみると、以下のような感じになりました。

wpf_avalondock_sharpgl

ドッキングもリサイズについてもうまく動いているようです。
このような 3D の画面をはめている場合においては上にコントロールを置くことは少ないでしょうし、領空問題と無縁でいられるかもしれません。

まとめ

意外にも WinFormsHost でも問題なく使えそうです。
最終の描画結果だけをはめたいという要望だと、D3DImage 方式の方が手数少なくいけそうな気がします。
しかし既に WinForms で実装したコントロール方式を持っていたり、これから OpenGL での描画コードも書く、といった条件では WPF にこだわらなくてもいいのかもと思いました。

今回の実験は全て Windows10 上で行いました。
もしかすると Windows7, WindowsXP といった環境ではうまくいかない可能性もあるかもしれません。

多少ですが 1つ気になった点がありました。
それは、 WinForms 版が初回表示時にはどうしても重い、という点です。
それあ SharpGL のせいなのか、WinForms を混在しているためなのかは詳しく調べていません。
今回の例で言えば起動時の1回だけですし、 D3DImage 版と違い、非表示状態を変えるだけで再初期化みたいなこともない点は、扱いやすそうに感じました。

OpenGLプログラミング
すらりんをフォローする
すらりん日記
タイトルとURLをコピーしました