前回、OpenTKの公式サイトでフリーダウンロードを推奨している「OpenTK.dllとOpenTK.GLControl.dllのバージョン不一致エラー問題」から、(感情的に)OpenTK導入に関わる癇癪玉を破裂させたので、今回はより客観的に書きたいと思います。
Windows 11に同梱されているC#コンパイラー(C#5)とMSCompAssによるプログラミング環境でOpenTKを利用される方は次の手順で設定を行ってください。
(1)OpenTK(Ver 3.3.3)とOpenTK.GLControl(Ver 3.3.3)をそれぞれダウンロードします。
(2)ダウンロードしたファイルは共に"*.nupkg"というファイル拡張子が付いていますが、これはエクスプローラーの「名前の変更」を使って"*.zip"ファイルにしてください。そのままエクスプローラーで中身が見えるようになります。
(3)両圧縮ファイルとも"lib"というフォールダー、その中に"net20"というフォールダーがありますので、その中から、"OpenTK.dll"と"OpenTK.GLControl.dll"というファイルを、C#のOPenTKプログラムを作成するフォールダーにコピーしてください。
(4)プログラムを作成し、MSCompAssでコンパイルする際には、
①プログラムの冒頭に、
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
//using OpenTK.Input;
という宣言を行ってください。
②"Option"ボタンで開くオプションダイアログの「参照」ボタンで、これら二つのDLLを選択してコンパイルしてください。
これだけでC#でOpenGLが使えるようになります。
と、いいたいのですが、
OpenGLはおろか、CGの基礎知識も乏しい私が簡単にグラフィックプログラムなど書けるわけもなく、
先ずはwebに散在するサンプルを動かしてみよう(テヘッ)
となるわけですが(注)、そこには大きく二つの問題が生じます。
注:実際は此処で最大、最恐のバージョン不一致問題に襲われるのですが...(怒)
(1)Visual Studioで作成されたプログラムしかないので、省略された自動作成コードを手作業で補完しなければならない
これはMSCompAssを使う際の宿命なのですが、webで見られるプログラムはVisual Studioで作られたものばかりで、Visual Studioga 自動作成する部分やファイルは自分でコードを手作業で補完しなければなりません。その為には書かれたプログラムを120%理解し、省略された部分を推定しなければなりませんが、webで見かけるサンプルはプログラム作法が大きく違うものがあることに気が付き、それはどうも、
①ウィンドウコントロールである"GLControl"を使ったプログラム
②OpenTKのGameWindowというクラスがあり、メインウィンドウをそれから派生させて作るプログラム
に大別されるようです。
(2)GLControlとGameWindowを使ったプログラムの違い、メリデメ、作法等を正しく理解する
要すればwebのサンプルプログラムを解析し、何をしているか理解しなければならない中で、この基本的な違いを正しく理解する必要があるわけですが、OpenTKのプログラミングを体系的にまとめたようなサイトが見当たらず、あーでもない、こーでもない、と推測、検証して理解してゆくのですが、これがなかなか手間です。
あっ、そうか!ChatGPT様にお願いしよう!
ということで、またぞろAIに頼ることになりました。以下はその問答の一部です。ご参考迄。
【ChatGPTにGLControlとGameWindowの違いを確認する】
User
またC#のOpenTK(OpenGL)について質問します。OpenTKを使う際、GLControlをメインフォームに貼り付けて使うのと、Gamewindowからメインフォームを派生させて使うのと二通りの使い方があると思いますが、それぞれのメリット、デメリットは何でしょう?
ChatGPT
OpenTKでのアプリケーション開発において、GLControl
を使用する方法とGameWindow
を用いる方法は、それぞれ異なるシナリオに最適です。それぞれの使い方のメリットとデメリットを以下にまとめます。
GLControlを使う場合
メリット:
-
GUIとの統合が容易:
GLControl
はWindows Formsのコントロールとして動作するため、他のUI要素(ボタン、テキストボックス等)と一緒に配置しやすく、従来のフォームベースのアプリケーションにOpenGLのレンダリング機能を追加する際に便利です。 -
デザイナーサポート: Visual Studioのデザイナーを使用して、フォーム上に
GLControl
をドラッグ&ドロップすることができ、GUIのレイアウトが直感的に行えます。 -
イベント駆動プログラミング: Windows Formsアプリケーションと同様に、イベントベースのプログラミングが可能です。これにより、ユーザー入力やその他のイベントを容易に処理できます。
デメリット:
-
パフォーマンスの限界:
GLControl
は、他のUIコンポーネントと共存するため、レンダリングの最適化やパフォーマンスがフルスクリーンのゲームや高度なグラフィックスアプリケーションほどではないかもしれません。 -
コンテキスト管理: OpenGLのコンテキスト管理が若干複雑になる可能性があり、マルチスレッド環境での使用や、他のグラフィックスAPIとの併用が難しい場合があります。
GameWindowを使う場合
メリット:
-
高パフォーマンス:
GameWindow
はゲームやリアルタイムシミュレーションに最適化されており、レンダリングパフォーマンスが最大化されています。これにより、より複雑なシーンや高速な更新が要求されるアプリケーションで有利です。 -
フルコントロール: 描画ループを完全に制御できるため、アプリケーションの振る舞いを細かくカスタマイズできます。
-
シンプルなコンテキスト管理: OpenGLのコンテキストが自動的に管理され、より直接的なグラフィックスプログラミングが可能です。
デメリット:
-
GUI統合の困難さ:
GameWindow
はGUIコンポーネントとの統合が困難で、外部ライブラリ(例:ImGui.NETなど)の使用が必要になる場合があります。 -
柔軟性の欠如: Windows FormsやWPFといった従来のデスクトップアプリケーションフレームワークの機能やコントロールを利用することが難しいです。
-
プラットフォーム依存性:
GameWindow
の挙動がプラットフォームによって異なる場合があり、クロスプラットフォーム開発での考慮が必要です。
結論
どちらの方法を選ぶかは、アプリケーションの要件と目的に強く依存します。GUIが重要な役割を果たすアプリケーションであればGLControl
、パフォーマンスが重要でリアルタイムのレンダリングが求められるアプリケーションであればGameWindow
が適しています。それぞれのメリットとデメリットを考慮して選択しましょう。
User
GLControlとGamewindowの両者はクラスになっていますが、メソッドや描画手順は共通するものがあるのでしょうか?
ChatGPT
GLControl
とGameWindow
は共にOpenTKライブラリで提供されているクラスで、OpenGLコンテキストを管理するための基本的な機能を提供しますが、それぞれの設計と使用法が異なります。ただし、OpenGLを使用する基本的なメソッドや描画手順には共通する部分があります。以下にその概要を示します。
共通する要素
-
OpenGL関数の使用:
GLControl
とGameWindow
のどちらを使用しても、OpenGLの関数(GL.*
)は同じです。これには、バッファの生成、シェーダのコンパイル、描画コマンドの発行などが含まれます。 -
イニシャライズ: OpenGLの環境設定やリソースの初期化は、どちらのクラスを使っても同様に行います。たとえば、テクスチャやバッファの生成、シェーダプログラムのセットアップなどです。
-
描画ループ: フレームごとの描画処理は、
GLControl
においては主にイベント(例えばPaint
イベント)で行われ、GameWindow
ではOnRenderFrame
メソッドをオーバーライドして行われます。どちらも同じOpenGLの描画コマンドを使います。
異なる要素
-
イベントハンドリング:
-
GLControl: Windows Formsベースであるため、通常のイベントハンドリング(
Click
,MouseMove
など)が使えます。また、Paint
イベントが描画のトリガーとして使われます。 -
GameWindow: OpenTKが提供する
OnUpdateFrame
,OnRenderFrame
などのライフサイクルメソッドをオーバーライドして使用します。これにより、フレーム更新や描画処理をより詳細にコントロールできます。
-
-
ウィンドウ管理:
-
GLControl:他のWindows Formsコントロールと同じように、フォームに追加される一つのUI要素です。フォームのライフサイクルに従います。
-
GameWindow:独自のウィンドウを持ち、そのライフサイクルを完全にコントロールします。これには、ウィンドウの作成、表示、クローズが含まれます。
-
例
以下は、GLControlとGameWindowの基本的な描画コードの例です。
-
GLControl (Windows Formsアプリケーション内):
C#
private void glControl1_Paint(object sender, PaintEventArgs e) {
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
//
描画コマンド
GL.Begin(PrimitiveType.Triangles);
GL.Vertex3(0.0f, 1.0f, 0.0f);
GL.Vertex3(1.0f, -1.0f, 0.0f);
GL.Vertex3(-1.0f, -1.0f, 0.0f);
GL.End();
glControl1.SwapBuffers();
}
-
GameWindow:
C#
protected override void OnRenderFrame(FrameEventArgs e) {
base.OnRenderFrame(e);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
//
描画コマンド
GL.Begin(PrimitiveType.Triangles);
GL.Vertex3(0.0f, 1.0f, 0.0f);
GL.Vertex3(1.0f, -1.0f, 0.0f);
GL.Vertex3(-1.0f, -1.0f, 0.0f);
GL.End();
SwapBuffers();
}
どちらもOpenGLの基本的な描画処理が行われていますが、イベント駆動かフレーム駆動かの違いがあります。この違いにより、どのコンテキストでどのクラスを選ぶかが決まります。
今回もChatGPT様の回答はとても簡潔で要を得ており、サンプルも動くようになりました。
が、
哀しい哉、私の3D CGやOpenGLに関する知見が乏しすぎて描画作法や描画方法等の基本がわかっておりません。また、OpenTKでそれらを学習しようとしても(既に旧いライブラリーであるOpenGL関連の記事は書きつくされており)OpenTKがらみでの記事は乏しいのが実態です。
一方、
3D CGやOpenGLに関する解説、学習記事等はGLUT(含freeglut、以下同じ)で豊富であり、前回書いたように
学習するならC++ plus GLUT(freeglut)ですやん!!
という方向に流れていくことになりました。
ということで、
これからは(話の端緒である)OpenTKを取り敢えず置いといて、再度このブログの主題であるBCCForm and BCCSkeltonでfreeglutを使って
「OpenGLの基本機能のデモプログラムを作ろう」
へと移ってゆきます。乞ご期待!