低レベルのネイティブプラグインインターフェース
Implement low-level rendering in your native plug-ins.
読み終わるまでの所要時間 7 分最終更新 1ヶ月前
Unity の ネイティブプラグインは、特定のイベントが発生したときにコールバックを受け取ることができます。これを利用して、プラグインに低レベルレンダリングを実装し、Unity のマルチスレッドレンダリングと連携できます。
インターフェースレジストリ
Unity のメインイベントをハンドルするには、プラグインは および の関数をエクスポートする必要があります。IUnityInterfaces を使用すると、プラグインがこれらの関数にアクセスすることができます。IUnityInterfaces は、プラグイン API の にあります。
UnityPluginLoadUnityPluginUnloadIUnityInterface.h#include "IUnityInterface.h"#include "IUnityGraphics.h"// Unity plugin load eventextern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces){ IUnityGraphics* graphics = unityInterfaces->Get<IUnityGraphics>();}
グラフィックスデバイスへのアクセス
IUnityGraphics.hIUnityGraphicsIUnityGraphics#include "IUnityInterface.h"#include "IUnityGraphics.h" static IUnityInterfaces* s_UnityInterfaces = NULL;static IUnityGraphics* s_Graphics = NULL;static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull; // Unity plugin load eventextern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces){ s_UnityInterfaces = unityInterfaces; s_Graphics = unityInterfaces->Get<IUnityGraphics>(); s_Graphics->RegisterDeviceEventCallback(OnGraphicsDeviceEvent); // Run OnGraphicsDeviceEvent(initialize) manually on plugin load // to not miss the event in case the graphics device is already initialized OnGraphicsDeviceEvent(kUnityGfxDeviceEventInitialize);} // Unity plugin unload eventextern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload(){ s_Graphics->UnregisterDeviceEventCallback(OnGraphicsDeviceEvent);} static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType){ switch (eventType) { case kUnityGfxDeviceEventInitialize: { s_RendererType = s_Graphics->GetRenderer(); //TODO: user initialization code on graphics device initialization. For example, D3D11 resource creation. break; } case kUnityGfxDeviceEventShutdown: { s_RendererType = kUnityGfxRendererNull; //TODO: user graphics API code to call on graphics device shutdown. break; } case kUnityGfxDeviceEventBeforeReset: { //TODO: user graphics API code to call before graphics device reset. break; } case kUnityGfxDeviceEventAfterReset: { //TODO: user graphics API code to call after graphics device reset. break; } };}
レンダースレッドのプラグインコールバック
プラットフォームと使用可能な CPU の数が許す限り、Unity でマルチスレッドを使用してレンダリングすることができます。
ノート: マルチスレッドレンダリングを使用すると、レンダリング API のコマンドは、MonoBehaviour スクリプトを実行するスレッドとは完全に別のスレッドで実行されます。メインスレッドとレンダースレッドの間で通信が行われるため、メインスレッドがレンダースレッドに渡した作業量によっては、プラグインがすぐにレンダリングを開始しない場合があります。
プラグインからレンダリングするには、マネージプラグインスクリプトから GL.IssuePluginEvent を呼び出します。これにより、以下のコード例に示すように、Unity のレンダーパイプラインがレンダースレッドからネイティブ関数を呼び出します。例えば、Camera の OnPostRender 関数から GL.IssuePluginEvent を呼び出すと、この関数は、カメラがレンダリングを終了するとすぐにプラグインコールバックを呼び出します。
ネイティブプラグインのコード
// Plugin function to handle a specific rendering eventstatic void UNITY_INTERFACE_API OnRenderEvent(int eventID){ // User rendering code} // Freely defined function to pass a callback to plugin-specific scriptsextern "C" UnityRenderingEvent UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API GetRenderEventFunc(){ return OnRenderEvent;}
マネージプラグインコード
#if UNITY_IPHONE && !UNITY_EDITOR[DllImport ("__Internal")]#else[DllImport("RenderingPlugin")]#endifprivate static extern IntPtr GetRenderEventFunc(); // Queue a specific callback to be called on the render threadGL.IssuePluginEvent(GetRenderEventFunc(), 1);
UnityRenderingEventOpenGL グラフィックス API を使用したプラグイン
OpenGL オブジェクトには 2 種類あります。
- OpenGL コンテキスト間で共有されるオブジェクト: テクスチャ、バッファ、レンダーバッファ、サンプラー、クエリ、シェーダー、 プログラムオブジェクトなど。
- OpenGLごとのコンテキストオブジェクト: 頂点配列、フレームバッファ、プログラムパイプライン、変換フィードバック、同期オブジェクトなど。
Unity は複数の OpenGL コンテキストを使用します。エディターとプレイヤーの起動時と終了時にはマスターコンテキストに依存し、レンダリング時には専用のコンテキストを使用します。つまり、 および のイベント中にコンテキストごとのオブジェクトを作成することはできません。
kUnityGfxDeviceEventInitializekUnityGfxDeviceEventShutdown