Xamarin.Mac での OpenTK の概要
OpenTK (The Open Toolkit) は、OpenGL、OpenCL、OpenAL の操作を容易にする先進の低レベル C# ライブラリです。 OpenTK は、3D グラフィックス、オーディオ、または計算機能を必要とするゲームや科学アプリケーションなどのプロジェクトに使用できます。 この記事では、Xamarin.Mac アプリでの OpenTK の使用について簡単に説明します。
この記事では、Xamarin.Mac アプリケーションでの OpenTK の基本について説明します。 この記事で使用する主要な概念と手法については、まず Hello Mac の記事、特に「Xcode と Interface Builder の概要」および「アウトレットとアクション」のセクションを参照することを強くお勧めします。
Xamarin.Mac Internals ドキュメントの 「C# クラス/メソッドの Objective-C への公開」のセクションも参照することをお勧めします。C# クラスを Objective-C オブジェクトと UI 要素に結び付けるために使われる Register
および Export
コマンドについて説明されています。
OpenTK について
前述のように、OpenTK (The Open Toolkit) は、OpenGL、OpenCL、OpenAL の操作を容易にする先進の低レベル C# ライブラリです。 Xamarin.Mac アプリで OpenTK を使用すると、次の機能が提供されます。
- 迅速な開発 - OpenTK は強力なデータ型とインライン ドキュメントを提供して、コーディング ワークフローを改善し、エラーをより簡単かつ迅速にキャッチします。
- 簡単な統合 - OpenTK は、.NET アプリケーションと簡単に統合できるように設計されています。
- パーミッシブ・ライセンス - OpenTK は MIT/X11 ライセンスに基づいて配布され、完全に無料です。
- 豊富なタイプセーフ バインディング - OpenTK では、拡張機能の自動読み込み、エラー チェック、インライン ドキュメントを備えた最新バージョンの OpenGL、OpenGL|ES、OpenAL、OpenCL がサポートされています。
- 柔軟な GUI オプション - OpenTK は、ゲームと Xamarin.Mac 専用に設計された高パフォーマンスのネイティブ ゲーム ウィンドウを提供します。
- フル マネージドの CLS 準拠コード - OpenTK では、アンマネージド ライブラリのない 32 ビット バージョンと 64 ビット バージョンの macOS がサポートされています。
- 3D Math Toolkit OpenTK は、3D Math Toolkit を介して、
Vector
、Matrix
、Quaternion
、Bezier
構造体を提供します。
OpenTK は、3D グラフィックス、オーディオ、または計算機能を必要とするゲームや科学アプリケーションなどのプロジェクトに使用できます。
詳細については、The Open Toolkit の Web サイトを参照してください。
OpenTK クイック スタート
Xamarin.Mac アプリでの OpenTK の使用に関する簡単な紹介として、ゲーム ビューを開き、そのビューで単純な三角形をレンダリングし、ゲーム ビューを Mac アプリのメイン ウィンドウにアタッチしてユーザーに三角形を表示する単純なアプリケーションを作成します。
新しいプロジェクトの開始
Visual Studio for Mac を起動し、新しい Xamarin.Mac ソリューションを作成します。 [Mac]>[アプリ]>[全般]>[Cocoa アプリ] を選択します。
[プロジェクト名] に MacOpenTK
を入力します。
[作成] ボタンをクリックして、新しいプロジェクトをビルドします。
OpenTK の組み込み
Xamarin.Mac アプリケーションで Open TK を使用するには、事前に OpenTK アセンブリへの参照を含める必要があります。 ソリューション エクスプローラーで、[参照] フォルダーを右クリックし、[参照の編集...] を選択します。
OpenTK
にチェックマークを付けて、[OK] ボタンをクリックします。
OpenTK の使用
新しいプロジェクトが作成されたら、ソリューション エクスプローラーで MainWindow.cs
ファイルをダブルクリックして、編集用に開きます。 MainWindow
クラスを次のようにします。
using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Platform.MacOS;
using Foundation;
using AppKit;
using CoreGraphics;
namespace MacOpenTK
{
public partial class MainWindow : NSWindow
{
#region Computed Properties
public MonoMacGameView Game { get; set; }
#endregion
#region Constructors
public MainWindow (IntPtr handle) : base (handle)
{
}
[Export ("initWithCoder:")]
public MainWindow (NSCoder coder) : base (coder)
{
}
#endregion
#region Override Methods
public override void AwakeFromNib ()
{
base.AwakeFromNib ();
// Create new Game View and replace the window content with it
Game = new MonoMacGameView(ContentView.Frame);
ContentView = Game;
Game.OpenGLContext.View = Game;
// Wire-up any required Game events
Game.Load += (sender, e) =>
{
// TODO: Initialize settings, load textures and sounds here
};
Game.Resize += (sender, e) =>
{
// Adjust the GL view to be the same size as the window
GL.Viewport(0, 0, Game.Size.Width, Game.Size.Height);
};
Game.UpdateFrame += (sender, e) =>
{
// TODO: Add any game logic or physics
};
Game.RenderFrame += (sender, e) =>
{
// Setup buffer
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.MatrixMode(MatrixMode.Projection);
// Draw a simple triangle
GL.LoadIdentity();
GL.Ortho(-1.0, 1.0, -1.0, 1.0, 0.0, 4.0);
GL.Begin(BeginMode.Triangles);
GL.Color3(Color.MidnightBlue);
GL.Vertex2(-1.0f, 1.0f);
GL.Color3(Color.SpringGreen);
GL.Vertex2(0.0f, -1.0f);
GL.Color3(Color.Ivory);
GL.Vertex2(1.0f, 1.0f);
GL.End();
};
// Run the game at 60 updates per second
Game.Run(60.0);
}
#endregion
}
}
このコードを以下で詳しく見てみましょう。
必要な API
Xamarin.Mac クラスで OpenTK を使用するには、いくつかの参照が必要です。 定義の開始時に、次の using
ステートメントが含まれています。
using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Platform.MacOS;
using Foundation;
using CoreGraphics;
この最小セットが、OpenTK を使用するすべてのクラスに必要です。
ゲーム ビューの追加
次に、OpenTK とのすべてのやり取りを含み、結果を表示するゲーム ビューを作成する必要があります。 次のコードを使用しました。
public MonoMacGameView Game { get; set; }
...
// Create new Game View and replace the window content with it
Game = new MonoMacGameView(ContentView.Frame);
ContentView = Game;
ここでは、ゲーム ビューをメイン Mac ウィンドウと同じサイズにし、ウィンドウのコンテンツ ビューを新しい MonoMacGameView
に置き換えています。 既存のウィンドウ コンテンツを置き換えたため、メイン ウィンドウのサイズを変更すると、ゲーム ビューのサイズが自動的に変更されます。
イベントへの応答
各ゲーム ビューが応答する既定のイベントがいくつかあります。 このセクションでは、必要なメイン イベントについて説明します。
Load イベント
Load
イベントは、イメージ、テクスチャ、音楽などのリソースをディスクから読み込む場所です。 単純なテスト アプリでは、Load
イベントを使用しませんが、参照用に含まれています。
Game.Load += (sender, e) =>
{
// TODO: Initialize settings, load textures and sounds here
};
Resize イベント
Resize
イベントは、ゲーム ビューのサイズが変更されるたびに呼び出されます。 サンプル アプリでは、次のコードを使用して、GL ビューポートをゲーム ビューと同じサイズにします (Mac メイン ウィンドウで自動的にサイズが変更されます)。
Game.Resize += (sender, e) =>
{
// Adjust the GL view to be the same size as the window
GL.Viewport(0, 0, Game.Size.Width, Game.Size.Height);
};
UpdateFrame イベント
UpdateFrame
イベントは、ユーザー入力の処理、オブジェクトの位置の更新、物理計算または AI 計算の実行に使用されます。 単純なテスト アプリでは、UpdateFrame
イベントを使用しませんが、参照用に含まれています。
Game.UpdateFrame += (sender, e) =>
{
// TODO: Add any game logic or physics
};
重要
Xamarin.Mac での OpenTK の実装には Input API
が含まれていないため、Apple が提供する API を使用してキーボードとマウスのサポートを追加する必要があります。 必要に応じて、MonoMacGameView
のカスタム インスタンスを作成し、KeyDown
および KeyUp
メソッドをオーバーライドできます。
RenderFrame イベント
RenderFrame
イベントには、グラフィックスのレンダリング (描画) に使用されるコードが含まれています。 サンプル アプリでは、ゲーム ビューに単純な三角形を埋め込みます。
Game.RenderFrame += (sender, e) =>
{
// Setup buffer
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.MatrixMode(MatrixMode.Projection);
// Draw a simple triangle
GL.LoadIdentity();
GL.Ortho(-1.0, 1.0, -1.0, 1.0, 0.0, 4.0);
GL.Begin(BeginMode.Triangles);
GL.Color3(Color.MidnightBlue);
GL.Vertex2(-1.0f, 1.0f);
GL.Color3(Color.SpringGreen);
GL.Vertex2(0.0f, -1.0f);
GL.Color3(Color.Ivory);
GL.Vertex2(1.0f, 1.0f);
GL.End();
};
通常、レンダリング コードでは、GL.Clear
を呼び出して、新しい要素を描画する前に既存の要素を削除します。
重要
Xamarin.Mac バージョンの OpenTK の場合、レンダリング コードの最後に MonoMacGameView
インスタンスの SwapBuffers
メソッドを呼び出さないでください。 これを行うと、レンダリングされたビューが表示されるのではなく、ゲーム ビューがすぐにストローブされます。
ゲーム ビューの実行
必要なすべてのイベントが定義され、アプリのメイン Mac ウィンドウにゲーム ビューがアタッチされた状態で、ゲーム ビューを実行してグラフィックスを表示する準備ができました。 次のコードを使用します。
// Run the game at 60 updates per second
Game.Run(60.0);
ゲーム ビューを更新する適切なフレーム レートを渡します。この例では、1 秒あたり 60
フレーム (通常のテレビと同じリフレッシュ レート) を選択しています。
アプリを実行し、出力を確認してみましょう。
ウィンドウのサイズを変更すると、ゲーム ビューのサイズも変更され、三角形もサイズが変更され、リアルタイムで更新されます。
次の場所
Xamarin.mac アプリケーションで OpenTk を操作する基本を確認したら、次に試す内容の提案をいくつか示します。
Load
とRenderFrame
イベントで三角形の色とゲーム ビューの背景色を変えてみます。- ユーザーが
UpdateFrame
とRenderFrame
イベントでキーを押すときに三角形の色を変えるか、または独自のカスタムMonoMacGameView
クラスを作成し、KeyUp
とKeyDown
メソッドをオーバーライドします。 UpdateFrame
イベントで対応キーを使用して、三角形を画面上で動かします。 ヒント:Matrix4.CreateTranslation
メソッドを使用して平行移動行列を作成し、GL.LoadMatrix
メソッドを呼び出してRenderFrame
イベントに読み込みます。for
ループを使用して、RenderFrame
イベントで複数の三角形をレンダリングします。- カメラを回転させて、3D 空間内で三角形の別のビューを表示します。 ヒント:
Matrix4.CreateTranslation
メソッドを使用して平行移動行列を作成し、GL.LoadMatrix
メソッドを呼び出して読み込みます。 カメラの操作にはVector2
、Vector3
、Vector4
、およびMatrix4
のクラスを使用することもできます。
その他の例については、OpenTK Samples GitHub リポジトリを参照してください。 OpenTK の使用例の公式の一覧が記載されています。 これらの例は、Xamarin.Mac バージョンの OpenTK で使用できるように調整する必要があります。
まとめ
この記事では、Xamarin.Mac アプリケーションでの OpenTK の使用について簡単に説明しました。 ゲーム ウィンドウを作成する方法、ゲーム ウィンドウを Mac ウィンドウにアタッチする方法、ゲーム ウィンドウで単純な図形をレンダリングする方法について説明しました。