Xamarin.Mac 中的 OpenTK 簡介

OpenTK (Open Toolkit) 是進階、低階 C# 連結庫,可讓您更輕鬆地使用 OpenGL、OpenCL 和 OpenAL。 OpenTK 可用於遊戲、科學應用程式或其他需要 3D 圖形、音訊或計算功能的專案。 本文提供在 Xamarin.Mac 應用程式中使用 OpenTK 的簡短簡介。

An example app run

在本文中,我們將討論 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 數學工具組提供VectorMatrixQuaternionBezier 結構。

OpenTK 可用於遊戲、科學應用程式或其他需要 3D 圖形、音訊或計算功能的專案。

如需詳細資訊,請參閱 Open Toolkit 網站。

OpenTK 快速入門

為了快速介紹在 Xamarin.Mac 應用程式中使用 OpenTK,我們將建立一個簡單的應用程式,以開啟遊戲檢視、在該檢視中呈現簡單的三角形,並將遊戲檢視附加至 Mac 應用程式的主視窗,以向用戶顯示三角形。

啟動新專案

啟動 Visual Studio for Mac 並建立新的 Xamarin.Mac 解決方案。 選取[Mac>應用程式>一般>Cocoa 應用程式]:

Adding a new Cocoa App

針對 [項目名稱] 輸入 MacOpenTK

Setting the project name

按兩下 [ 建立] 按鈕以建置新的專案。

包含 OpenTK

您必須先包含 OpenTK 元件的參考,才能在 Xamarin.Mac 應用程式中使用 Open TK。 在 方案總管 中,以滑鼠右鍵按兩下 [參考] 資料夾,然後選取 [編輯參考...]。

按下 [確定] 按鈕進行檢查OpenTK

Editing the project references

使用 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 自定義實例,並覆寫 KeyDownKeyUp 方法。

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 每秒的畫面格(與一般電視相同的重新整理速率)。

讓我們執行應用程式並檢視輸出:

A sample of the apps output

如果我們調整視窗的大小,遊戲檢視也會位於 ,而且三角形也會即時重設大小和更新。

下一步?

完成 Xamarin.mac 應用程式中使用 OpenTk 的基本概念,以下是接下來要嘗試的一些建議:

  • 請嘗試在和 RenderFrame 事件中Load變更三角形的色彩和遊戲檢視的背景色彩。
  • 當使用者按下 和 事件中的UpdateFrame按鍵,或建立您自己的自定義MonoMacGameView類別並覆寫 KeyUpKeyDown 方法時,讓三角形變更RenderFrame色彩。
  • 使用事件中的 UpdateFrame 感知索引鍵,讓三角形在畫面上移動。 提示:使用 Matrix4.CreateTranslation 方法來建立轉譯矩陣,並呼叫 GL.LoadMatrix 方法以在 事件中 RenderFrame 載入它。
  • for使用迴圈在 事件中RenderFrame轉譯數個三角形。
  • 旋轉相機以在 3D 空間中提供三角形的不同檢視。 提示:使用 Matrix4.CreateTranslation 方法來建立轉譯矩陣,並呼叫 GL.LoadMatrix 方法來載入它。 您也可以使用Vector2Vector3Vector4Matrix4 類別來進行相機操作。

如需更多範例,請參閱 OpenTK 範例 GitHub 存放庫。 其中包含使用 OpenTK 的正式範例清單。 您必須調整這些範例,才能搭配 OpenTK 的 Xamarin.Mac 版本使用。

如需 OpenTK 實作更複雜的 Xamarin.Mac 範例,請參閱 MonoMacGameView 範例。

摘要

本文已快速探討在 Xamarin.Mac 應用程式中使用 OpenTK。 我們已瞭解如何建立遊戲視窗、如何將遊戲視窗附加至 Mac 視窗,以及如何在遊戲視窗中呈現簡單的圖形。