OpenGLにはバージョン1.3以降の機能が
エクステンション(拡張機能)として用意されているわけですが、
それらを使用するためにはちょっとひと手間必要になるので、
ここでは、C#でエクステンションを使用するための手順を書いておきます。
エクステンションを使用する場合は、
まずは、その実行環境(グラフィックボードとか)で実装されているOpenGLのバージョンと
使用できるエクステンションのリストを取得して、
使いたいエクステンションがサポートされているかどうかをチェックする。
バージョンは、
glGetString( GL_VERSION );
サポートされているエクステンションのリストは、
glGetString( GL_EXTENTONS );
で、スペース区切りで並んだ文字列をして取得できる。
OpenTKなら、
bool GL.SupportsExtension( string name )
というメソッドにエクステンションの名前を渡すと、
それがサポートされているかどうかを返してくれる。
ついでに、GLSharpにGLExtensionNamesという、
エクステンションの名前を文字列定数として持つクラスを作っておいたので、
そこから名前をGL.SupportsExtensionメソッドに渡せばOK。
各エクステンションの一覧や詳細等は、
OpenGLの本家サイトに掲載されてます。
OpenGL Extension Registry
OpenTKやTaoをラッパーとして使用しているのであれば、
エクステンションがサポートされているのを確認できたら
後はそのまま拡張関数を呼び出すことができる。
ちなみに、サポートされていない関数を呼び出すと例外が発生する。
ラッパーに頼らずにエクステンションを使用する場合は
以下の手順を踏む必要があるので、
さらに手間が掛かることになる。
Windows環境においてエクステンションで面倒なのは、
エクステンションの拡張関数は、
レンダリングコンテキストを作成した後、
プログラム内で動的に関数ポインタを取得しないと使用できない、
というところ。
C#なら、
それぞれの関数に応じたデリゲートを宣言して、
関数ポインタからそのデリゲートのインスタンスに変換する、
という作業になる。
拡張関数のポインタは、
wglGetProcAddress関数に
拡張関数の名前を文字列で渡すことで取得できる。
C#での宣言はこんな感じ。
[DllImport( "opengl32.dll", EntryPoint = "wglGetProcAddress" ), System.Security.SuppressUnmanagedCodeSecurity]
public static extern IntPtr GetProcAddress( string functionName );
こうして取得したポインタは、
System.Runtime.InteropServices.Marshal.GetDelegateForFunctionPointer
というメソッドに、変換するデリゲートの型と共に渡すことで、
デリゲートのインスタンスへ変換できる。
このデリゲートを使用することで、拡張関数を呼び出す。