Xamarin.Mac 中的 OpenTK 簡介
OpenTK (Open Toolkit) 是進階、低階 C# 連結庫,可讓您更輕鬆地使用 OpenGL、OpenCL 和 OpenAL。 OpenTK 可用於遊戲、科學應用程式或其他需要 3D 圖形、音訊或計算功能的專案。 本文提供在 Xamarin.Mac 應用程式中使用 OpenTK 的簡短簡介。
在本文中,我們將討論 Xamarin.Mac 應用程式中 OpenTK 的基本概念。 強烈建議您先完成 Hello,Mac 文章,特別是 Xcode 和 Interface Builder 和 Outlets 和 Actions 簡介小節,因為它涵蓋我們將在本文中使用的重要概念和技術。
您可能也想要查看 Xamarin.Mac Internals 檔的公開 C# 類別/方法Objective-C一節,它也會說明 Register
用來將 C# 類別連接至Objective-C物件和 UI 元素的 和 Export
命令。
關於 OpenTK
如上所述,OpenTK (Open Toolkit) 是進階、低階 C# 連結庫,可讓您更輕鬆地使用 OpenGL、OpenCL 和 OpenAL。 在 Xamarin.Mac 應用程式中使用 OpenTK 提供下列功能:
- 快速開發 - OpenTK 提供強大的數據類型和內嵌檔,可改善您的程式代碼撰寫工作流程,並更快速地攔截錯誤。
- 簡易整合 - OpenTK 的設計目的是要輕鬆地與 .NET 應用程式整合。
- 寬鬆授權 - OpenTK 會以 MIT/X11 授權散發,且完全免費。
- 豐富、類型 保管庫 系結 - OpenTK 支援最新版本的 OpenGL、OpenGL|ES、OpenAL 和 OpenCL,以及自動載入延伸模組、錯誤檢查和內嵌檔。
- 彈性 GUI 選項 - OpenTK 提供專為遊戲和 Xamarin.Mac 設計的原生高效能遊戲視窗。
- 完全受控、符合 CLS 規範的程式代碼 - OpenTK 支援沒有 Unmanaged 連結庫的 32 位和 64 位版本的 macOS。
- 3D 數學工具組 OpenTK 透過其 3D 數學工具組提供
Vector
、Matrix
Quaternion
和Bezier
結構。
OpenTK 可用於遊戲、科學應用程式或其他需要 3D 圖形、音訊或計算功能的專案。
如需詳細資訊,請參閱 Open Toolkit 網站。
OpenTK 快速入門
為了快速介紹在 Xamarin.Mac 應用程式中使用 OpenTK,我們將建立一個簡單的應用程式,以開啟遊戲檢視、在該檢視中呈現簡單的三角形,並將遊戲檢視附加至 Mac 應用程式的主視窗,以向用戶顯示三角形。
啟動新專案
啟動 Visual Studio for Mac 並建立新的 Xamarin.Mac 解決方案。 選取[Mac>應用程式>一般>Cocoa 應用程式]:
針對 [項目名稱] 輸入 MacOpenTK
:
按兩下 [ 建立] 按鈕以建置新的專案。
包含 OpenTK
您必須先包含 OpenTK 元件的參考,才能在 Xamarin.Mac 應用程式中使用 Open TK。 在 方案總管 中,以滑鼠右鍵按兩下 [參考] 資料夾,然後選取 [編輯參考...]。
按下 [確定] 按鈕進行檢查OpenTK
:
使用 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
};
重要
OpenTK 的 Xamarin.Mac 實作不包含 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
來移除任何現有的專案。
重要
針對 OpenTK 的 Xamarin.Mac 版本,請勿 在轉譯程式代碼結尾呼叫 SwapBuffers
實例的方法 MonoMacGameView
。 這樣做會導致遊戲檢視快速跳動,而不是顯示轉譯的檢視。
執行遊戲檢視
透過定義所有必要的事件,以及連結至應用程式主 Mac 視窗的遊戲檢視,我們會閱讀以執行遊戲檢視並顯示圖形。 使用下列程式碼:
// Run the game at 60 updates per second
Game.Run(60.0);
我們傳入我們想要遊戲檢視更新的所需幀速率,例如,我們已選擇 60
每秒的畫面格(與一般電視相同的重新整理速率)。
讓我們執行應用程式並檢視輸出:
如果我們調整視窗的大小,遊戲檢視也會位於 ,而且三角形也會即時重設大小和更新。
下一步?
完成 Xamarin.mac 應用程式中使用 OpenTk 的基本概念,以下是接下來要嘗試的一些建議:
- 請嘗試在和
RenderFrame
事件中Load
變更三角形的色彩和遊戲檢視的背景色彩。 - 當使用者按下 和 事件中的
UpdateFrame
按鍵,或建立您自己的自定義MonoMacGameView
類別並覆寫KeyUp
和KeyDown
方法時,讓三角形變更RenderFrame
色彩。 - 使用事件中的
UpdateFrame
感知索引鍵,讓三角形在畫面上移動。 提示:使用Matrix4.CreateTranslation
方法來建立轉譯矩陣,並呼叫GL.LoadMatrix
方法以在 事件中RenderFrame
載入它。 for
使用迴圈在 事件中RenderFrame
轉譯數個三角形。- 旋轉相機以在 3D 空間中提供三角形的不同檢視。 提示:使用
Matrix4.CreateTranslation
方法來建立轉譯矩陣,並呼叫GL.LoadMatrix
方法來載入它。 您也可以使用Vector2
、Vector3
Vector4
和Matrix4
類別來進行相機操作。
如需更多範例,請參閱 OpenTK 範例 GitHub 存放庫。 其中包含使用 OpenTK 的正式範例清單。 您必須調整這些範例,才能搭配 OpenTK 的 Xamarin.Mac 版本使用。
摘要
本文已快速探討在 Xamarin.Mac 應用程式中使用 OpenTK。 我們已瞭解如何建立遊戲視窗、如何將遊戲視窗附加至 Mac 視窗,以及如何在遊戲視窗中呈現簡單的圖形。