『.Net で GLSL』 はフォームに直接描画していたので、コントロールに描画してみます。
画面分割して左に描画、右にプロパティなどを置ける感じのサンプルです。
作った時の環境。GLEW を導入してない方は こちら 。
大体こんな感じで作ります。
前回作った GLSLApp.zip を元に作るのでダウンロード。
GLSLForm.h をクリックしてデザイナを開き、ツールボックスから SplitContainer をフォームに配置します。
左に描画, 右にコントロールを配置するものとして、大体以下のようにサイズを調整。
めんどくさい人は、このまま左に pictureBox 置くなり、panel1 に直接描画するなりしてもいいんですが、
折角なので再描画でチラつかないようカスタムコントロールを作成してみます。
OpenGL 描画用のコントロールは背景消去を無効にしたいので、Control を継承した新しいクラスを作成して使います。
プロジェクト名を右クリックして「 追加>新しい項目>クラス 」を選択。
「 C++ クラス 」で追加ボタンを押し、クラス名に GLSLView, 継承元クラスに System::Windows::Forms::Control を入力して完了。
生成された GLSLView.h に OnPaintBackground を追加してオーバーライド。( 赤字 )
[GLSLView.h] #pragma once using namespace System::Windows::Forms; ref class GLSLView : public System::Windows::Forms::Control { public: GLSLView(void); protected: virtual System::Void OnPaintBackground(PaintEventArgs^ e) override { // 何もしない } };
GLSLForm.h に GLSLView のヘッダファイルとメンバ変数を追加します。( 赤字 )
[GLSLForm.h] #include "GLSLMain.h" #include "GLSLView.h"
private: GLSLMain* m_pGL; GLSLView^ m_view;コンストラクタで Panel1 の子に追加し、DockStype を Fill に設定します。( 赤字 )
public: GLSLForm(void) { InitializeComponent(); // //TODO: ここにコンストラクター コードを追加します // m_view = gcnew GLSLView(); m_view->Dock = System::Windows::Forms::DockStyle::Fill; this->splitContainer1->Panel1->Controls->Add(m_view); m_pGL = new GLSLMain((void*)this->Handle); }
フォームのコンストラクタで GLSLView に Paint, SizeChanged イベントを追加します。
既にあるフォーム本体のイベントをコピってきて、this を m_view に差し替えればOK。
[GLSLForm.h] m_view->Paint += gcnew System::Windows::Forms::PaintEventHandler(this, &GLSLForm::GLSLForm_Paint); m_view->SizeChanged += gcnew System::EventHandler(this, &GLSLForm::GLSLForm_SizeChanged);
フォームのコンストラクタで m_pGL に渡すウィンドウハンドルを GLSLView のものに変更します。( 赤字 )
m_pGL = new GLSLMain((void*)m_view->Handle);
最後に Paint, SizeChanged で Render に渡すウィンドウサイズを GLSLView のサイズにします。
private: System::Void GLSLForm_Paint(System::Object^ sender, System::Windows::Forms::PaintEventArgs^ e) { if (m_pGL) m_pGL->Render(m_view->ClientSize.Width, m_view->ClientSize.Height); } System::Void GLSLForm_SizeChanged(System::Object^ sender, System::EventArgs^ e) { if (m_pGL) m_pGL->Render(m_view->ClientSize.Width, m_view->ClientSize.Height); }
シェーダを変更したり、パラメータを変更したりするのにコントロール使いたかったのでその準備です。
しかし標準コントロールに描画するとチラつくし、部品化してツールボックスに読み込んで使うと Express でデザイナ表示できない…。
なのでデザイナ経由せずにカスタムコントロールを作って追加していますが、もっと簡単な方法ないですかね。
今回はスプリッターで左右分割してますが、そのへんは用途に合わせてご自由に。