OpenTKを用いてOpenGLプログラミングする

ゲームエンジンの内部実装に興味があったので、思い切ってはじめてみた。 実装言語は自分が書き慣れているC#で、グラフィックライブラリは、VulkanやMetalなどモダンな物はあるものの、まずはOpenGLではじめることにした。

C#でOpenGLを扱うライブラリとして、調べるとOpenGL.NetSilk.NETOpenTKopengl4csharpあたりが引っかかったが、今でも開発が頻繁そうなOpenTKを利用することにした。

OpenTKのTKはToolkitの頭文字で、OpenGLやOpenAL、OpenCLの薄いラッパーを提供するライブラリ。

GUIを作る上で面倒なウインドウシステムや、マウスやキーボードなどの入力処理も提供されていて、これらの実装は最新のバージョンであるv4ではGLFWベースで書かれている。

環境構築

先述の通り、最新のOpenTKはglfwベースで書かれているので、glfwのインストールが必要になる。homebrewでは下記のようにインストールできる。

$ brew install glfw

あとは、C#のプロジェクトを作成して、そのプロジェクトにNuGetなどのパッケージマネジャーで[OpenTK](https://www.nuget.org/packages/OpenTK/_をインストールする。.NET CLIでは下記のようにインストールできる。

$ dotnet add package OpenTK --version 4.0.6

余談だが.NET CLIでプロジェクトは下記のコマンドで作成できる。下記はコンソールアプリケーションの空プロジェクトを作成している。

$ dotnet new console

ウインドウの表示

公式ドキュメントはv3のAPIで書かれているのでサンプルがそのまま動かないが、概ねそのまま動く。自身のプロジェクトではでは下記で空ウインドウを表示できた。

using OpenTK.Windowing.Common;
using OpenTK.Windowing.Desktop;

namespace Minity
{
    public class MinityWindow : GameWindow
    {
        public MinityWindow() : base(
            new GameWindowSettings()
            {
                RenderFrequency = 60.0,
                UpdateFrequency = 60.0,
            },
            new NativeWindowSettings()
            {
                APIVersion = new System.Version(3, 2),
                Flags = ContextFlags.ForwardCompatible,
            }
        )
        {
        }
    }
}

ウインドウの基底クラスのGameWindowの名前空間がOpenTK.Windowing.Desktopに移動している。また著者はmacOSなので、基底のコンストラクタにNativeWindowSettingsでOpenGLのバージョンを指定している点が異なる。 macOSではOpenGLのバージョンを3.2に指定し、かつContextFlags.ForwardCompatibleを指定(前方互換プロファイル、つまり古い機能を使えないよう指定)しないと起動できない。

ちなみに、macOSで利用できる(厳密にはマシンに搭載されているグラフィックボードに依存している)OpenGLのバージョンは、https://developer.apple.com/opengl/OpenGL-Capabilities-Tables.pdfで確認できる。

あとは、上記のウインドウをエントリポイントから呼び出す。

using System;

namespace Minity
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var window = new MinityWindow())
            {
                window.Run();
            }
        }
    }
}

全容はこちら

参考